diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/account.ftl b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/account.ftl
new file mode 100755
index 0000000000000000000000000000000000000000..a0d86c9ee26b9ec0f5ef88a8c555d197b9a99c06
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/account.ftl
@@ -0,0 +1,80 @@
+<#import "template.ftl" as layout>
+<@layout.mainLayout active='account' bodyClass='user'; section>
+
+    <div class="row">
+        <div class="col-md-10">
+            <h2>${msg("editAccountHtmlTitle")}</h2>
+        </div>
+        <div class="col-md-2 subtitle">
+            <span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
+        </div>
+    </div>
+
+    <form action="${url.accountUrl}" class="form-horizontal" method="post">
+
+        <input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
+
+        <#if !realm.registrationEmailAsUsername>
+            <div class="form-group ${messagesPerField.printIfExists('username','has-error')}">
+                <div class="col-sm-2 col-md-2">
+                    <label for="username" class="control-label">${msg("username")}</label> <#if realm.editUsernameAllowed><span class="required">*</span></#if>
+                </div>
+
+                <div class="col-sm-10 col-md-10">
+                    <input type="text" class="form-control" id="username" name="username" <#if !realm.editUsernameAllowed>disabled="disabled"</#if> value="${(account.username!'')}"/>
+                </div>
+            </div>
+        </#if>
+
+        <div class="form-group ${messagesPerField.printIfExists('email','has-error')}">
+            <div class="col-sm-2 col-md-2">
+            <label for="email" class="control-label">${msg("email")}</label> <span class="required">*</span>
+            </div>
+
+            <div class="col-sm-10 col-md-10">
+                <input type="text" class="form-control" id="email" name="email" autofocus value="${(account.email!'')}"/>
+            </div>
+        </div>
+
+        <div class="form-group ${messagesPerField.printIfExists('firstName','has-error')}">
+            <div class="col-sm-2 col-md-2">
+                <label for="firstName" class="control-label">${msg("firstName")}</label> <span class="required">*</span>
+            </div>
+
+            <div class="col-sm-10 col-md-10">
+                <input type="text" class="form-control" id="firstName" name="firstName" value="${(account.firstName!'')}"/>
+            </div>
+        </div>
+
+        <div class="form-group ${messagesPerField.printIfExists('lastName','has-error')}">
+            <div class="col-sm-2 col-md-2">
+                <label for="lastName" class="control-label">${msg("lastName")}</label> <span class="required">*</span>
+            </div>
+
+            <div class="col-sm-10 col-md-10">
+                <input type="text" class="form-control" id="lastName" name="lastName" value="${(account.lastName!'')}"/>
+            </div>
+        </div>
+
+        <div class="form-group ${messagesPerField.printIfExists('mailPassword','has-error')}">
+            <div class="col-sm-2 col-md-2">
+                <label for="mailPassword" class="control-label">${msg("mailPassword")}</label> <span class="required">*</span>
+            </div>
+
+            <div class="col-sm-10 col-md-10">
+                <input type="password" class="form-control" id="mailPassword" name="mailPassword" value="${(account.mailPassword!'')}"/>
+            </div>
+        </div>
+
+        <div class="form-group">
+            <div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
+                <div class="">
+                    <#if url.referrerURI??><a href="${url.referrerURI}">${kcSanitize(msg("backToApplication")?no_esc)}</a></#if>
+                    <button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Save">${msg("doSave")}</button>
+                    <button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="Cancel">${msg("doCancel")}</button>
+                </div>
+            </div>
+        </div>
+    </form>
+
+</@layout.mainLayout>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/index.ftl b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/index.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..236954873b113ca41c3647b9d4af00304edd402c
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/index.ftl
@@ -0,0 +1,279 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>${msg("accountManagementTitle")}</title>
+
+        <meta charset="UTF-8">
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+        <meta name="robots" content="noindex, nofollow">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+
+        <script>
+            <#if properties.developmentMode?has_content && properties.developmentMode == "true">
+            var developmentMode = true;
+            var reactRuntime = 'react.development.js';
+            var reactDOMRuntime = 'react-dom.development.js';
+            var reactRouterRuntime = 'react-router-dom.js';
+            <#else>
+            var developmentMode = false;
+            var reactRuntime = 'react.production.min.js';
+            var reactDOMRuntime = 'react-dom.production.min.js';
+            var reactRouterRuntime = 'react-router-dom.min.js';
+            </#if>
+            var authUrl = '${authUrl}';
+            var baseUrl = '${baseUrl}';
+            var realm = '${realm.name}';
+            var resourceUrl = '${resourceUrl}';
+            var isReactLoading = false;
+
+            <#if properties.logo?has_content>
+            var brandImg = resourceUrl + '${properties.logo}';
+            <#else>
+            var brandImg = resourceUrl + '/public/archlinux-logo-light.svg';
+            </#if>
+
+            <#if properties.logoUrl?has_content>
+            var brandUrl = '${properties.logoUrl}';
+            <#else>
+            var brandUrl = baseUrl;
+            </#if>
+
+            var features = {
+                isRegistrationEmailAsUsername : ${realm.registrationEmailAsUsername?c},
+                isEditUserNameAllowed : ${realm.editUsernameAllowed?c},
+                isInternationalizationEnabled : ${realm.isInternationalizationEnabled()?c},
+                isLinkedAccountsEnabled : ${realm.identityFederationEnabled?c},
+                isEventsEnabled : ${isEventsEnabled?c},
+                isMyResourcesEnabled : ${(realm.userManagedAccessAllowed && isAuthorizationEnabled)?c},
+                isTotpConfigured : ${isTotpConfigured?c},
+                deleteAccountAllowed : ${deleteAccountAllowed?c}
+            }
+
+            var availableLocales = [];
+            <#list supportedLocales as locale, label>
+                availableLocales.push({locale : '${locale}', label : '${label}'});
+            </#list>
+
+            <#if referrer??>
+                var referrer = '${referrer}';
+                var referrerName = '${referrerName}';
+                var referrerUri = '${referrer_uri?no_esc}';
+            </#if>
+
+            <#if msg??>
+                var locale = '${locale}';
+                var l18nMsg = JSON.parse('${msgJSON?no_esc}');
+            <#else>
+                var locale = 'en';
+                var l18Msg = {};
+            </#if>
+        </script>
+
+        <#if properties.favIcon?has_content>
+        <link rel="icon" href="${resourceUrl}${properties.favIcon}" type="image/x-icon"/>
+        <#else>
+        <link rel="icon" href="${resourceUrl}/public/archlinux-favicon.ico" type="image/x-icon"/>
+        </#if>
+
+        <script src="${authUrl}js/keycloak.js"></script>
+
+        <#if properties.developmentMode?has_content && properties.developmentMode == "true">
+        <!-- Don't use this in production: -->
+        <script src="${resourceUrl}/node_modules/react/umd/react.development.js" crossorigin></script>
+        <script src="${resourceUrl}/node_modules/react-dom/umd/react-dom.development.js" crossorigin></script>
+        <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
+        </#if>
+
+        <#if properties.extensions?has_content>
+            <#list properties.extensions?split(' ') as script>
+                <#if properties.developmentMode?has_content && properties.developmentMode == "true">
+        <script type="text/babel" src="${resourceUrl}/${script}"></script>
+                <#else>
+        <script type="text/javascript" src="${resourceUrl}/${script}"></script>
+                </#if>
+            </#list>
+        </#if>
+
+        <#if properties.scripts?has_content>
+            <#list properties.scripts?split(' ') as script>
+        <script type="text/javascript" src="${resourceUrl}/${script}"></script>
+            </#list>
+        </#if>
+
+        <script>
+            var content = <#include "resources/content.json"/>
+        </script>
+
+        <#if properties.styles?has_content>
+            <#list properties.styles?split(' ') as style>
+            <link href="${resourceUrl}/${style}" rel="stylesheet"/>
+            </#list>
+        </#if>
+
+        <link rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/react-core/dist/styles/base.css"/>
+        <link rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/react-core/dist/styles/app.css"/>
+        <link href="${resourceUrl}/public/layout.css" rel="stylesheet"/>
+    </head>
+
+    <body>
+
+        <script>
+            const keycloak = Keycloak({
+                authServerUrl: authUrl,
+                realm: realm,
+                clientId: 'account-console'
+            });
+            keycloak.init({onLoad: 'check-sso', pkceMethod: 'S256', promiseType: 'native'}).then((authenticated) => {
+                isReactLoading = true;
+                toggleReact();
+                if (!keycloak.authenticated) {
+                    document.getElementById("landingSignInButton").style.display='inline';
+                    document.getElementById("landingSignInLink").style.display='inline';
+                } else {
+                    document.getElementById("landingSignOutButton").style.display='inline';
+                    document.getElementById("landingSignOutLink").style.display='inline';
+                    document.getElementById("landingLoggedInUser").innerHTML = loggedInUserName('${msg("unknownUser")}', '${msg("fullName")}');
+                }
+
+                loadjs("/Main.js");
+            }).catch(() => {
+                alert('failed to initialize keycloak');
+            });
+        </script>
+
+<div id="main_react_container" style="display:none;height:100%"></div>
+
+<div id="spinner_screen" style="display:block; height:100%">
+    <div style="width: 320px; height: 328px; text-align: center; position: absolute; top:0;	bottom: 0; left: 0;	right: 0; margin: auto;">
+                <#if properties.logo?has_content>
+                <img src="${resourceUrl}${properties.logoDark}" alt="Logo" class="brand">
+                <#else>
+                <img src="${resourceUrl}/public/archlinux-logo-dark.svg" alt="Logo" class="brand">
+                </#if>
+                <p>${msg("loadingMessage")}</p>
+                <div >
+                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
+                    <path d="M10 50A40 40 0 0 0 90 50A40 42 0 0 1 10 50" fill="#5DBCD2" stroke="none" transform="rotate(16.3145 50 51)">
+                        <animateTransform attributeName="transform" type="rotate" dur="1s" repeatCount="indefinite" keyTimes="0;1" values="0 50 51;360 50 51"></animateTransform>
+                    </path>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div id="welcomeScreen" style="display:none;height:100%">
+    <div class="pf-c-page" id="page-layout-default-nav">
+      <header role="banner" class="pf-c-page__header">
+        <div class="pf-c-page__header-brand">
+          <#if properties.logoUrl?has_content>
+          <a id="landingLogo" class="pf-c-page__header-brand-link" href="${properties.logoUrl}">
+          <#else>
+          <a id="landingLogo" class="pf-c-page__header-brand-link" href="${baseUrl}">
+          </#if>
+            <#if properties.logo?has_content>
+            <img class="pf-c-brand brand" src="${resourceUrl}${properties.logo}" alt="Logo">
+            <#else>
+            <img class="pf-c-brand brand" src="${resourceUrl}/public/archlinux-logo-light.svg" alt="Logo">
+            </#if>
+          </a>
+        </div>
+        <div class="pf-c-page__header-tools">
+            <#if referrer?has_content && referrer_uri?has_content>
+            <div class="pf-c-page__header-tools-group pf-m-icons">
+              <a id="landingReferrerLink" href="${referrer_uri}" id="referrer" tabindex="0"><span class="pf-icon pf-icon-arrow"></span>${msg("backTo",referrerName)}</a>
+            </div>
+            </#if>
+
+            <div class="pf-c-page__header-tools-group pf-m-icons">
+              <button id="landingSignInButton" tabindex="0" style="display:none" onclick="keycloak.login();" class="pf-c-button pf-m-primary" type="button">${msg("doSignIn")}</button>
+              <button id="landingSignOutButton" tabindex="0" style="display:none" onclick="keycloak.logout();" class="pf-c-button pf-m-primary" type="button">${msg("doSignOut")}</button>
+            </div>
+
+            <!-- Kebab for mobile -->
+            <div class="pf-c-page__header-tools-group">
+                <div id="landingMobileKebab" class="pf-c-dropdown pf-m-mobile" onclick="toggleMobileDropdown();"> <!-- pf-m-expanded -->
+                    <button aria-label="Actions" tabindex="0" id="landingMobileKebabButton" class="pf-c-dropdown__toggle pf-m-plain" type="button" aria-expanded="true" aria-haspopup="true">
+                        <svg fill="currentColor" height="1em" width="1em" viewBox="0 0 192 512" aria-hidden="true" role="img" style="vertical-align: -0.125em;"><path d="M96 184c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72zM24 80c0 39.8 32.2 72 72 72s72-32.2 72-72S135.8 8 96 8 24 40.2 24 80zm0 352c0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72-72 32.2-72 72z" transform=""></path></svg>
+                    </button>
+                    <ul id="landingMobileDropdown" aria-labelledby="landingMobileKebabButton" class="pf-c-dropdown__menu pf-m-align-right" role="menu" style="display:none">
+                        <#if referrer?has_content && referrer_uri?has_content>
+                        <li role="none">
+                            <a id="landingMobileReferrerLink" href="${referrer_uri}" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("backTo",referrerName)}</a>
+                        </li>
+                        </#if>
+
+                        <li id="landingSignInLink" role="none" style="display:none">
+                            <a onclick="keycloak.login();" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("doLogIn")}</a>
+                        </li>
+                        <li id="landingSignOutLink" role="none" style="display:none">
+                            <a onclick="keycloak.logout();" role="menuitem" tabindex="0" aria-disabled="false" class="pf-c-dropdown__menu-item">${msg("doSignOut")}</a>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+
+            <span id="landingLoggedInUser"></span>
+
+        </div> <!-- end header tools -->
+      </header>
+
+      <main role="main" class="pf-c-page__main">
+        <section class="pf-c-page__main-section pf-m-light">
+          <div class="pf-c-content" id="landingWelcomeMessage">
+            <h1>${msg("accountManagementWelcomeMessage")}</h1>
+          </div>
+        </section>
+        <section class="pf-c-page__main-section">
+          <div class="pf-l-gallery pf-m-gutter">
+            <#assign content=theme.apply("content.json")?eval>
+            <#list content as item>
+              <div class="pf-l-gallery__item pf-c-card" id="landing-${item.id}">
+                <div>
+                  <div class="pf-c-card__header pf-c-content">
+                      <h2>
+                        <#if item.icon??>
+                          <i class="pf-icon ${item.icon}"></i>&nbsp;
+                        <#elseif item.iconSvg??>
+                          <img src="${item.iconSvg}" alt="icon"/>&nbsp;
+                        </#if>
+                        ${msg(item.label)}
+                      </h2>
+                      <#if item.descriptionLabel??>
+                        <p>${msg(item.descriptionLabel)}</p>
+                      </#if>
+                  </div>
+                  <div class="pf-c-card__body pf-c-content">
+                    <#if item.content??>
+                      <#list item.content as sub>
+                        <div id="landing-${sub.id}">
+                          <a onclick="toggleReact(); window.location.hash='${sub.path}'">${msg(sub.label)}</a>
+                        </div>
+                      </#list>
+                    <#else>
+                      <a id="landing-${item.id}" onclick="toggleReact(); window.location.hash = '${item.path}'">${msg(item.label)}</a>
+                    </#if>
+                  </div>
+                </div>
+              </div>
+            </#list>
+          </div>
+        </section>
+      </main>
+    </div>
+</div>
+
+    <script>
+      const removeHidden = (content) => {
+        content.forEach(c => {
+          if (c.hidden && eval(c.hidden)) {
+            document.getElementById('landing-' + c.id).remove();
+          }
+          if (c.content) removeHidden(c.content);
+        });
+      }
+      removeHidden(content);
+    </script>
+
+    </body>
+</html>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/messages/messages_en.properties b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/messages/messages_en.properties
new file mode 100755
index 0000000000000000000000000000000000000000..904efa7e677a20d737b98446a2af4d5e9623f666
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/messages/messages_en.properties
@@ -0,0 +1,2 @@
+personalSubMessageAuth=Manage this basic information: your first name, last name, email and mail password
+mailPassword=Mail password
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/AccountServiceContext.js b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/AccountServiceContext.js
new file mode 100644
index 0000000000000000000000000000000000000000..a5aec7bb15e91c32255f4387ec6ae958809c174a
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/AccountServiceContext.js
@@ -0,0 +1,3 @@
+import * as React from "../../../common/keycloak/web_modules/react.js";
+export const AccountServiceContext = React.createContext(undefined);
+//# sourceMappingURL=AccountServiceContext.js.map
\ No newline at end of file
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/AccountServiceContext.js.map b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/AccountServiceContext.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..1fa9f2ba11477b4c279b4047c31f588f1ab50c64
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/AccountServiceContext.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../../src/app/account-service/AccountServiceContext.tsx"],"names":["React","AccountServiceContext","createContext","undefined"],"mappings":"AAAA,OAAO,KAAKA,KAAZ;AAGA,OAAO,MAAMC,qBAAqB,GAAGD,KAAK,CAACE,aAAN,CAAsDC,SAAtD,CAA9B","sourcesContent":["import * as React from 'react';\nimport { AccountServiceClient } from './account.service';\n\nexport const AccountServiceContext = React.createContext<AccountServiceClient | undefined>(undefined);"],"file":"AccountServiceContext.js"}
\ No newline at end of file
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/account.service.js b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/account.service.js
new file mode 100644
index 0000000000000000000000000000000000000000..b72e2c1e350cf29c51f7531b7b07ef628652826b
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/account.service.js
@@ -0,0 +1,185 @@
+function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+/*
+ * Copyright 2018 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+import { ContentAlert } from "../content/ContentAlert.js";
+export class AccountServiceError extends Error {
+  constructor(response) {
+    super(response.statusText);
+    this.response = response;
+  }
+
+}
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.
+ */
+
+export class AccountServiceClient {
+  constructor(keycloakService) {
+    _defineProperty(this, "kcSvc", void 0);
+
+    _defineProperty(this, "accountUrl", void 0);
+
+    _defineProperty(this, "mailPassUrl", void 0);
+
+    this.kcSvc = keycloakService;
+    this.accountUrl = this.kcSvc.authServerUrl() + 'realms/' + this.kcSvc.realm() + '/account';
+    this.mailPassUrl = this.kcSvc.authServerUrl() + 'realms/' + this.kcSvc.realm() + '/mailpass/roleauth/compute-password-hash';
+  }
+
+  checkToken() {
+    return this.kcSvc.authenticated();
+  }
+
+  checkRealmRole(role) {
+    return this.kcSvc.realmRole(role);
+  }
+
+  async doPost2(endpoint, body, config) {
+    return this.doRequest2(endpoint, { ...config,
+      body: JSON.stringify(body),
+      method: 'post'
+    });
+  }
+
+  async doRequest2(endpoint, config) {
+    const response = await fetch(this.makeUrl2(endpoint, config).toString(), (await this.makeConfig(config)));
+    let data = "";
+
+    try {
+      data = await response.text();
+    } catch (e) {} // ignore.  Might be empty
+
+
+    if (!response.ok) {
+      this.handleError(response);
+      throw new AccountServiceError(response);
+    }
+
+    return data;
+  }
+
+  makeUrl2(endpoint, config) {
+    if (endpoint.startsWith('http')) return new URL(endpoint);
+    const url = new URL(this.mailPassUrl + endpoint); // add request params
+
+    if (config && config.hasOwnProperty('params')) {
+      const params = config.params || {};
+      Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
+    }
+
+    return url;
+  }
+
+  async doGet(endpoint, config) {
+    return this.doRequest(endpoint, { ...config,
+      method: 'get'
+    });
+  }
+
+  async doDelete(endpoint, config) {
+    return this.doRequest(endpoint, { ...config,
+      method: 'delete'
+    });
+  }
+
+  async doPost(endpoint, body, config) {
+    return this.doRequest(endpoint, { ...config,
+      body: JSON.stringify(body),
+      method: 'post'
+    });
+  }
+
+  async doPut(endpoint, body, config) {
+    return this.doRequest(endpoint, { ...config,
+      body: JSON.stringify(body),
+      method: 'put'
+    });
+  }
+
+  async doRequest(endpoint, config) {
+    const response = await fetch(this.makeUrl(endpoint, config).toString(), (await this.makeConfig(config)));
+
+    try {
+      response.data = await response.json();
+    } catch (e) {} // ignore.  Might be empty
+
+
+    if (!response.ok) {
+      this.handleError(response);
+      throw new AccountServiceError(response);
+    }
+
+    return response;
+  }
+
+  handleError(response) {
+    if (response !== null && response.status === 401) {
+      // session timed out?
+      this.kcSvc.login();
+    }
+
+    if (response !== null && response.status === 403) {
+      window.location.href = baseUrl + '/#/forbidden';
+    }
+
+    if (response !== null && response.data != null) {
+      ContentAlert.danger(`${response.statusText}: ${response.data['errorMessage'] ? response.data['errorMessage'] : ''} ${response.data['error'] ? response.data['error'] : ''}`);
+    } else {
+      ContentAlert.danger(response.statusText);
+    }
+  }
+
+  makeUrl(endpoint, config) {
+    if (endpoint.startsWith('http')) return new URL(endpoint);
+    const url = new URL(this.accountUrl + endpoint); // add request params
+
+    if (config && config.hasOwnProperty('params')) {
+      const params = config.params || {};
+      Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
+    }
+
+    return url;
+  }
+
+  makeConfig(config = {}) {
+    return new Promise(resolve => {
+      this.kcSvc.getToken().then(token => {
+        resolve({ ...config,
+          headers: {
+            'Content-Type': 'application/json',
+            ...config.headers,
+            Authorization: 'Bearer ' + token
+          }
+        });
+      }).catch(() => {
+        this.kcSvc.login();
+      });
+    });
+  }
+
+}
+window.addEventListener("unhandledrejection", event => {
+  event.promise.catch(error => {
+    if (error instanceof AccountServiceError) {
+      // We already handled the error. Ignore unhandled rejection.
+      event.preventDefault();
+    }
+  });
+});
+//# sourceMappingURL=account.service.js.map
\ No newline at end of file
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/account.service.js.map b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/account.service.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..8a59ecf2f7a85aa612ff9154b226f20d011ec2fb
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/account-service/account.service.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../../src/app/account-service/account.service.ts"],"names":["ContentAlert","AccountServiceError","Error","constructor","response","statusText","AccountServiceClient","keycloakService","kcSvc","accountUrl","authServerUrl","realm","mailPassUrl","checkToken","authenticated","checkRealmRole","role","realmRole","doPost2","endpoint","body","config","doRequest2","JSON","stringify","method","fetch","makeUrl2","toString","makeConfig","data","text","e","ok","handleError","startsWith","URL","url","hasOwnProperty","params","Object","keys","forEach","key","searchParams","append","doGet","doRequest","doDelete","doPost","doPut","makeUrl","json","status","login","window","location","href","baseUrl","danger","Promise","resolve","getToken","then","token","headers","Authorization","catch","addEventListener","event","promise","error","preventDefault"],"mappings":";;AAAA;;;;;;;;;;;;;;;;AAkBA,SAAQA,YAAR;AAcA,OAAO,MAAMC,mBAAN,SAAkCC,KAAlC,CAAwC;AAC3CC,EAAAA,WAAW,CAAQC,QAAR,EAAgC;AACvC,UAAMA,QAAQ,CAACC,UAAf;AADuC,SAAxBD,QAAwB,GAAxBA,QAAwB;AAE1C;;AAH0C;AAM/C;;;;;AAIA,OAAO,MAAME,oBAAN,CAA2B;AAKvBH,EAAAA,WAAP,CAAmBI,eAAnB,EAAqD;AAAA;;AAAA;;AAAA;;AACjD,SAAKC,KAAL,GAAaD,eAAb;AACA,SAAKE,UAAL,GAAkB,KAAKD,KAAL,CAAWE,aAAX,KAA6B,SAA7B,GAAyC,KAAKF,KAAL,CAAWG,KAAX,EAAzC,GAA8D,UAAhF;AACA,SAAKC,WAAL,GAAmB,KAAKJ,KAAL,CAAWE,aAAX,KAA6B,SAA7B,GAAyC,KAAKF,KAAL,CAAWG,KAAX,EAAzC,GAA8D,0CAAjF;AACH;;AAEME,EAAAA,UAAP,GAAoB;AAChB,WAAO,KAAKL,KAAL,CAAWM,aAAX,EAAP;AACH;;AAEMC,EAAAA,cAAP,CAAsBC,IAAtB,EAAmC;AAC/B,WAAO,KAAKR,KAAL,CAAWS,SAAX,CAAqBD,IAArB,CAAP;AACH;;AAED,QAAaE,OAAb,CAAwBC,QAAxB,EACsBC,IADtB,EAEsBC,MAFtB,EAEuE;AACnE,WAAO,KAAKC,UAAL,CAAgBH,QAAhB,EAA0B,EAAC,GAAGE,MAAJ;AAAYD,MAAAA,IAAI,EAAEG,IAAI,CAACC,SAAL,CAAeJ,IAAf,CAAlB;AAAwCK,MAAAA,MAAM,EAAE;AAAhD,KAA1B,CAAP;AACH;;AAED,QAAaH,UAAb,CAA2BH,QAA3B,EAC0BE,MAD1B,EAC2E;AAEvE,UAAMjB,QAAyB,GAAG,MAAMsB,KAAK,CAAC,KAAKC,QAAL,CAAcR,QAAd,EAAwBE,MAAxB,EAAgCO,QAAhC,EAAD,GACC,MAAM,KAAKC,UAAL,CAAgBR,MAAhB,CADP,EAA7C;AAGA,QAAIS,IAAI,GAAG,EAAX;;AACA,QAAI;AACAA,MAAAA,IAAI,GAAG,MAAM1B,QAAQ,CAAC2B,IAAT,EAAb;AACH,KAFD,CAEE,OAAOC,CAAP,EAAU,CAAE,CARyD,CAQxD;;;AAEf,QAAI,CAAC5B,QAAQ,CAAC6B,EAAd,EAAkB;AACd,WAAKC,WAAL,CAAiB9B,QAAjB;AACA,YAAM,IAAIH,mBAAJ,CAAwBG,QAAxB,CAAN;AACH;;AAED,WAAO0B,IAAP;AACH;;AAEOH,EAAAA,QAAR,CAAiBR,QAAjB,EAAmCE,MAAnC,EAAwE;AACpE,QAAIF,QAAQ,CAACgB,UAAT,CAAoB,MAApB,CAAJ,EAAiC,OAAO,IAAIC,GAAJ,CAAQjB,QAAR,CAAP;AACjC,UAAMkB,GAAG,GAAG,IAAID,GAAJ,CAAQ,KAAKxB,WAAL,GAAmBO,QAA3B,CAAZ,CAFoE,CAIpE;;AACA,QAAIE,MAAM,IAAIA,MAAM,CAACiB,cAAP,CAAsB,QAAtB,CAAd,EAA+C;AAC3C,YAAMC,MAAgC,GAAGlB,MAAM,CAACkB,MAAP,IAAuB,EAAhE;AACAC,MAAAA,MAAM,CAACC,IAAP,CAAYF,MAAZ,EAAoBG,OAApB,CAA4BC,GAAG,IAAIN,GAAG,CAACO,YAAJ,CAAiBC,MAAjB,CAAwBF,GAAxB,EAA6BJ,MAAM,CAACI,GAAD,CAAnC,CAAnC;AACH;;AAED,WAAON,GAAP;AACH;;AAGD,QAAaS,KAAb,CAAsB3B,QAAtB,EACsBE,MADtB,EACgF;AAC5E,WAAO,KAAK0B,SAAL,CAAe5B,QAAf,EAAyB,EAAC,GAAGE,MAAJ;AAAYI,MAAAA,MAAM,EAAE;AAApB,KAAzB,CAAP;AACH;;AAED,QAAauB,QAAb,CAAyB7B,QAAzB,EACwBE,MADxB,EACkF;AAC9E,WAAO,KAAK0B,SAAL,CAAe5B,QAAf,EAAyB,EAAC,GAAGE,MAAJ;AAAYI,MAAAA,MAAM,EAAE;AAApB,KAAzB,CAAP;AACH;;AAED,QAAawB,MAAb,CAAuB9B,QAAvB,EACsBC,IADtB,EAEsBC,MAFtB,EAEgF;AAC5E,WAAO,KAAK0B,SAAL,CAAe5B,QAAf,EAAyB,EAAC,GAAGE,MAAJ;AAAYD,MAAAA,IAAI,EAAEG,IAAI,CAACC,SAAL,CAAeJ,IAAf,CAAlB;AAAwCK,MAAAA,MAAM,EAAE;AAAhD,KAAzB,CAAP;AACH;;AAED,QAAayB,KAAb,CAAsB/B,QAAtB,EACqBC,IADrB,EAEqBC,MAFrB,EAE+E;AAC3E,WAAO,KAAK0B,SAAL,CAAe5B,QAAf,EAAyB,EAAC,GAAGE,MAAJ;AAAYD,MAAAA,IAAI,EAAEG,IAAI,CAACC,SAAL,CAAeJ,IAAf,CAAlB;AAAwCK,MAAAA,MAAM,EAAE;AAAhD,KAAzB,CAAP;AACH;;AAED,QAAasB,SAAb,CAA0B5B,QAA1B,EAC0BE,MAD1B,EACoF;AAEhF,UAAMjB,QAAyB,GAAG,MAAMsB,KAAK,CAAC,KAAKyB,OAAL,CAAahC,QAAb,EAAuBE,MAAvB,EAA+BO,QAA/B,EAAD,GACC,MAAM,KAAKC,UAAL,CAAgBR,MAAhB,CADP,EAA7C;;AAGA,QAAI;AACAjB,MAAAA,QAAQ,CAAC0B,IAAT,GAAgB,MAAM1B,QAAQ,CAACgD,IAAT,EAAtB;AACH,KAFD,CAEE,OAAOpB,CAAP,EAAU,CAAE,CAPkE,CAOjE;;;AAEf,QAAI,CAAC5B,QAAQ,CAAC6B,EAAd,EAAkB;AACd,WAAKC,WAAL,CAAiB9B,QAAjB;AACA,YAAM,IAAIH,mBAAJ,CAAwBG,QAAxB,CAAN;AACH;;AAED,WAAOA,QAAP;AACH;;AAEO8B,EAAAA,WAAR,CAAoB9B,QAApB,EAAkD;AAC9C,QAAIA,QAAQ,KAAK,IAAb,IAAqBA,QAAQ,CAACiD,MAAT,KAAoB,GAA7C,EAAkD;AAC9C;AACA,WAAK7C,KAAL,CAAW8C,KAAX;AACH;;AAED,QAAIlD,QAAQ,KAAK,IAAb,IAAqBA,QAAQ,CAACiD,MAAT,KAAoB,GAA7C,EAAkD;AAC9CE,MAAAA,MAAM,CAACC,QAAP,CAAgBC,IAAhB,GAAuBC,OAAO,GAAG,cAAjC;AACH;;AAED,QAAItD,QAAQ,KAAK,IAAb,IAAqBA,QAAQ,CAAC0B,IAAT,IAAiB,IAA1C,EAAgD;AAC5C9B,MAAAA,YAAY,CAAC2D,MAAb,CACK,GAAEvD,QAAQ,CAACC,UAAW,KAAID,QAAQ,CAAC0B,IAAT,CAAc,cAAd,IAAgC1B,QAAQ,CAAC0B,IAAT,CAAc,cAAd,CAAhC,GAAgE,EAAG,IAAG1B,QAAQ,CAAC0B,IAAT,CAAc,OAAd,IAAyB1B,QAAQ,CAAC0B,IAAT,CAAc,OAAd,CAAzB,GAAkD,EAAG,EAD1J;AAGH,KAJD,MAIO;AACH9B,MAAAA,YAAY,CAAC2D,MAAb,CAAoBvD,QAAQ,CAACC,UAA7B;AACH;AACJ;;AAEO8C,EAAAA,OAAR,CAAgBhC,QAAhB,EAAkCE,MAAlC,EAAuE;AACnE,QAAIF,QAAQ,CAACgB,UAAT,CAAoB,MAApB,CAAJ,EAAiC,OAAO,IAAIC,GAAJ,CAAQjB,QAAR,CAAP;AACjC,UAAMkB,GAAG,GAAG,IAAID,GAAJ,CAAQ,KAAK3B,UAAL,GAAkBU,QAA1B,CAAZ,CAFmE,CAInE;;AACA,QAAIE,MAAM,IAAIA,MAAM,CAACiB,cAAP,CAAsB,QAAtB,CAAd,EAA+C;AAC3C,YAAMC,MAAgC,GAAGlB,MAAM,CAACkB,MAAP,IAAuB,EAAhE;AACAC,MAAAA,MAAM,CAACC,IAAP,CAAYF,MAAZ,EAAoBG,OAApB,CAA4BC,GAAG,IAAIN,GAAG,CAACO,YAAJ,CAAiBC,MAAjB,CAAwBF,GAAxB,EAA6BJ,MAAM,CAACI,GAAD,CAAnC,CAAnC;AACH;;AAED,WAAON,GAAP;AACH;;AAEOR,EAAAA,UAAR,CAAmBR,MAAmB,GAAG,EAAzC,EAAmE;AAC/D,WAAO,IAAIuC,OAAJ,CAAcC,OAAD,IAA4B;AAC5C,WAAKrD,KAAL,CAAWsD,QAAX,GACKC,IADL,CACYC,KAAD,IAAmB;AACtBH,QAAAA,OAAO,CAAE,EACL,GAAGxC,MADE;AAEL4C,UAAAA,OAAO,EAAE;AAAC,4BAAgB,kBAAjB;AACA,eAAG5C,MAAM,CAAC4C,OADV;AAECC,YAAAA,aAAa,EAAE,YAAYF;AAF5B;AAFJ,SAAF,CAAP;AAMH,OARL,EAQOG,KARP,CAQa,MAAM;AACX,aAAK3D,KAAL,CAAW8C,KAAX;AACH,OAVL;AAWH,KAZM,CAAP;AAaH;;AAhJ6B;AAoJlCC,MAAM,CAACa,gBAAP,CAAwB,oBAAxB,EAA+CC,KAAD,IAAkC;AAC5EA,EAAAA,KAAK,CAACC,OAAN,CAAcH,KAAd,CAAoBI,KAAK,IAAI;AACzB,QAAIA,KAAK,YAAYtE,mBAArB,EAA0C;AACtC;AACAoE,MAAAA,KAAK,CAACG,cAAN;AACH;AACJ,GALD;AAMH,CAPD","sourcesContent":["/*\n * Copyright 2018 Red Hat Inc. and/or its affiliates and other contributors\n * as indicated by the @author tags. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy of\n * the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */\n\nimport {KeycloakService} from '../keycloak-service/keycloak.service';\nimport {ContentAlert} from '../content/ContentAlert';\n\ndeclare const baseUrl: string;\n\ntype ConfigResolve = (config: RequestInit) => void;\n\nexport interface HttpResponse<T = {}> extends Response {\n    data?: T;\n}\n\nexport interface RequestInitWithParams extends RequestInit {\n    params?: {[name: string]: string | number};\n}\n\nexport class AccountServiceError extends Error {\n    constructor(public response: HttpResponse) {\n        super(response.statusText);\n    }\n}\n\n/**\n *\n * @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.\n */\nexport class AccountServiceClient {\n    private kcSvc: KeycloakService;\n    private accountUrl: string;\n    private mailPassUrl: string;\n\n    public constructor(keycloakService: KeycloakService) {\n        this.kcSvc = keycloakService;\n        this.accountUrl = this.kcSvc.authServerUrl() + 'realms/' + this.kcSvc.realm() + '/account';\n        this.mailPassUrl = this.kcSvc.authServerUrl() + 'realms/' + this.kcSvc.realm() + '/mailpass/roleauth/compute-password-hash';\n    };\n\n    public checkToken() {\n        return this.kcSvc.authenticated();\n    }\n\n    public checkRealmRole(role:string) {\n        return this.kcSvc.realmRole(role);\n    }\n\n    public async doPost2<T>(endpoint: string,\n                          body: string | {},\n                          config?: RequestInitWithParams): Promise<string> {\n        return this.doRequest2(endpoint, {...config, body: JSON.stringify(body), method: 'post'});\n    }\n\n    public async doRequest2<T>(endpoint: string,\n                              config?: RequestInitWithParams): Promise<string> {\n\n        const response: HttpResponse<T> = await fetch(this.makeUrl2(endpoint, config).toString(),\n                                                      await this.makeConfig(config));\n\n        let data = \"\";\n        try {\n            data = await response.text();\n        } catch (e) {} // ignore.  Might be empty\n\n        if (!response.ok) {\n            this.handleError(response);\n            throw new AccountServiceError(response);\n        }\n\n        return data;\n    }\n\n    private makeUrl2(endpoint: string, config?: RequestInitWithParams): URL {\n        if (endpoint.startsWith('http')) return new URL(endpoint);\n        const url = new URL(this.mailPassUrl + endpoint);\n\n        // add request params\n        if (config && config.hasOwnProperty('params')) {\n            const params: {[name: string]: string} = config.params as {} || {};\n            Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))\n        }\n\n        return url;\n    }\n\n\n    public async doGet<T>(endpoint: string,\n                          config?: RequestInitWithParams): Promise<HttpResponse<T>> {\n        return this.doRequest(endpoint, {...config, method: 'get'});\n    }\n\n    public async doDelete<T>(endpoint: string,\n                            config?: RequestInitWithParams): Promise<HttpResponse<T>> {\n        return this.doRequest(endpoint, {...config, method: 'delete'});\n    }\n\n    public async doPost<T>(endpoint: string,\n                          body: string | {},\n                          config?: RequestInitWithParams): Promise<HttpResponse<T>> {\n        return this.doRequest(endpoint, {...config, body: JSON.stringify(body), method: 'post'});\n    }\n\n    public async doPut<T>(endpoint: string,\n                         body: string | {},\n                         config?: RequestInitWithParams): Promise<HttpResponse<T>> {\n        return this.doRequest(endpoint, {...config, body: JSON.stringify(body), method: 'put'});\n    }\n\n    public async doRequest<T>(endpoint: string,\n                              config?: RequestInitWithParams): Promise<HttpResponse<T>> {\n\n        const response: HttpResponse<T> = await fetch(this.makeUrl(endpoint, config).toString(),\n                                                      await this.makeConfig(config));\n\n        try {\n            response.data = await response.json();\n        } catch (e) {} // ignore.  Might be empty\n\n        if (!response.ok) {\n            this.handleError(response);\n            throw new AccountServiceError(response);\n        }\n\n        return response;\n    }\n\n    private handleError(response: HttpResponse): void {\n        if (response !== null && response.status === 401) {\n            // session timed out?\n            this.kcSvc.login();\n        }\n\n        if (response !== null && response.status === 403) {\n            window.location.href = baseUrl + '/#/forbidden';\n        }\n\n        if (response !== null && response.data != null) {\n            ContentAlert.danger(\n                `${response.statusText}: ${response.data['errorMessage'] ? response.data['errorMessage'] : ''} ${response.data['error'] ? response.data['error'] : ''}`\n            );\n        } else {\n            ContentAlert.danger(response.statusText);\n        }\n    }\n\n    private makeUrl(endpoint: string, config?: RequestInitWithParams): URL {\n        if (endpoint.startsWith('http')) return new URL(endpoint);\n        const url = new URL(this.accountUrl + endpoint);\n\n        // add request params\n        if (config && config.hasOwnProperty('params')) {\n            const params: {[name: string]: string} = config.params as {} || {};\n            Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))\n        }\n\n        return url;\n    }\n\n    private makeConfig(config: RequestInit = {}): Promise<RequestInit> {\n        return new Promise( (resolve: ConfigResolve) => {\n            this.kcSvc.getToken()\n                .then( (token: string) => {\n                    resolve( {\n                        ...config,\n                        headers: {'Content-Type': 'application/json',\n                                 ...config.headers,\n                                  Authorization: 'Bearer ' + token}\n                    });\n                }).catch(() => {\n                    this.kcSvc.login();\n                });\n        });\n    }\n\n}\n\nwindow.addEventListener(\"unhandledrejection\", (event: PromiseRejectionEvent) => {\n    event.promise.catch(error => {\n        if (error instanceof AccountServiceError) {\n            // We already handled the error. Ignore unhandled rejection.\n            event.preventDefault();\n        }\n    });\n});\n"],"file":"account.service.js"}
\ No newline at end of file
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/content/account-page/AccountPage.js b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/content/account-page/AccountPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..5eb268cac46ccc991793de3a38e6de719231e539
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/content/account-page/AccountPage.js
@@ -0,0 +1,316 @@
+function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import * as React from "../../../../common/keycloak/web_modules/react.js";
+import { ActionGroup, Button, Form, FormGroup, TextInput, Grid, GridItem, Expandable } from "../../../../common/keycloak/web_modules/@patternfly/react-core.js";
+import { AccountServiceContext } from "../../account-service/AccountServiceContext.js";
+import { Msg } from "../../widgets/Msg.js";
+import { ContentPage } from "../ContentPage.js";
+import { ContentAlert } from "../ContentAlert.js";
+import { LocaleSelector } from "../../widgets/LocaleSelectors.js";
+import { KeycloakContext } from "../../keycloak-service/KeycloakContext.js";
+import { AIACommand } from "../../util/AIACommand.js";
+
+/**
+ * @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.
+ */
+export class AccountPage extends React.Component {
+  constructor(props, context) {
+    super(props);
+
+    _defineProperty(this, "context", void 0);
+
+    _defineProperty(this, "isRegistrationEmailAsUsername", features.isRegistrationEmailAsUsername);
+
+    _defineProperty(this, "isEditUserNameAllowed", features.isEditUserNameAllowed);
+
+    _defineProperty(this, "isDeleteAccountAllowed", features.deleteAccountAllowed);
+
+    _defineProperty(this, "DEFAULT_STATE", {
+      errors: {
+        username: '',
+        firstName: '',
+        lastName: '',
+        email: ''
+      },
+      formFields: {
+        username: '',
+        firstName: '',
+        lastName: '',
+        email: '',
+        attributes: {}
+      }
+    });
+
+    _defineProperty(this, "state", this.DEFAULT_STATE);
+
+    _defineProperty(this, "handleCancel", () => {
+      this.fetchPersonalInfo();
+    });
+
+    _defineProperty(this, "handleChange", (value, event) => {
+      const target = event.currentTarget;
+      const name = target.name;
+      this.setState({
+        errors: { ...this.state.errors,
+          [name]: target.validationMessage
+        },
+        formFields: { ...this.state.formFields,
+          [name]: value
+        }
+      });
+    });
+
+    _defineProperty(this, "handleSubmit", event => {
+      event.preventDefault();
+      const form = event.target;
+      const isValid = form.checkValidity();
+
+      if (isValid) {
+        let mailPass = this.state.formFields.attributes.mailPassword;
+        this.getHash(mailPass).then(res => {
+          this.setState({
+            errors: this.state.errors,
+            formFields: { ...this.state.formFields,
+              attributes: { ...this.state.formFields.attributes,
+                mailPassword: res
+              }
+            }
+          });
+          const reqData = { ...this.state.formFields
+          };
+          this.context.doPost("/", reqData).then(() => {
+            ContentAlert.success('accountUpdatedMessage');
+
+            if (locale !== this.state.formFields.attributes.locale[0]) {
+              window.location.reload();
+            }
+          });
+        });
+      } else {
+        const formData = new FormData(form);
+        const validationMessages = Array.from(formData.keys()).reduce((acc, key) => {
+          acc[key] = form.elements[key].validationMessage;
+          return acc;
+        }, {});
+        this.setState({
+          errors: { ...validationMessages
+          },
+          formFields: this.state.formFields
+        });
+      }
+    });
+
+    _defineProperty(this, "handleDelete", keycloak => {
+      new AIACommand(keycloak, "delete_account").execute();
+    });
+
+    _defineProperty(this, "UsernameInput", () => React.createElement(TextInput, {
+      isRequired: true,
+      type: "text",
+      id: "user-name",
+      name: "username",
+      maxLength: 254,
+      value: this.state.formFields.username,
+      onChange: this.handleChange,
+      isValid: this.state.errors.username === ''
+    }));
+
+    _defineProperty(this, "RestrictedUsernameInput", () => React.createElement(TextInput, {
+      isDisabled: true,
+      type: "text",
+      id: "user-name",
+      name: "username",
+      value: this.state.formFields.username
+    }));
+
+    this.context = context;
+    this.fetchPersonalInfo();
+  }
+
+  fetchPersonalInfo() {
+    this.context.doGet("/").then(response => {
+      this.setState(this.DEFAULT_STATE);
+      const formFields = response.data;
+
+      if (!formFields.attributes) {
+        formFields.attributes = {
+          locale: [locale]
+        };
+      } else if (!formFields.attributes.locale) {
+        formFields.attributes.locale = [locale];
+      }
+
+      this.setState({ ...{
+          formFields: formFields
+        }
+      });
+    });
+  }
+
+  async getHash(value) {
+    let data = {
+      password: value
+    };
+    let response = await this.context.doPost2("/", data);
+    return response;
+  }
+
+  showMailPassField() {
+    let awesome = keycloak.tokenParsed?.realm_access?.roles.includes("staff") || false;
+    return awesome;
+  }
+
+  render() {
+    const fields = this.state.formFields;
+    return React.createElement(ContentPage, {
+      title: "personalInfoHtmlTitle",
+      introMessage: this.showMailPassField() ? "personalSubMessageAuth" : "personalSubMessage"
+    }, React.createElement(Form, {
+      isHorizontal: true,
+      onSubmit: event => this.handleSubmit(event)
+    }, !this.isRegistrationEmailAsUsername && React.createElement(FormGroup, {
+      label: Msg.localize('username'),
+      isRequired: true,
+      fieldId: "user-name",
+      helperTextInvalid: this.state.errors.username,
+      isValid: this.state.errors.username === ''
+    }, this.isEditUserNameAllowed && React.createElement(this.UsernameInput, null), !this.isEditUserNameAllowed && React.createElement(this.RestrictedUsernameInput, null)), React.createElement(FormGroup, {
+      label: Msg.localize('email'),
+      isRequired: true,
+      fieldId: "email-address",
+      helperTextInvalid: this.state.errors.email,
+      isValid: this.state.errors.email === ''
+    }, React.createElement(TextInput, {
+      isRequired: true,
+      type: "email",
+      id: "email-address",
+      name: "email",
+      maxLength: 254,
+      value: fields.email,
+      onChange: this.handleChange,
+      isValid: this.state.errors.email === ''
+    })), React.createElement(FormGroup, {
+      label: Msg.localize('firstName'),
+      isRequired: true,
+      fieldId: "first-name",
+      helperTextInvalid: this.state.errors.firstName,
+      isValid: this.state.errors.firstName === ''
+    }, React.createElement(TextInput, {
+      isRequired: true,
+      type: "text",
+      id: "first-name",
+      name: "firstName",
+      maxLength: 254,
+      value: fields.firstName,
+      onChange: this.handleChange,
+      isValid: this.state.errors.firstName === ''
+    })), React.createElement(FormGroup, {
+      label: Msg.localize('lastName'),
+      isRequired: true,
+      fieldId: "last-name",
+      helperTextInvalid: this.state.errors.lastName,
+      isValid: this.state.errors.lastName === ''
+    }, React.createElement(TextInput, {
+      isRequired: true,
+      type: "text",
+      id: "last-name",
+      name: "lastName",
+      maxLength: 254,
+      value: fields.lastName,
+      onChange: this.handleChange,
+      isValid: this.state.errors.lastName === ''
+    })), this.showMailPassField() && React.createElement(FormGroup, {
+      label: Msg.localize('mailPassword'),
+      isRequired: true,
+      fieldId: "mail-password"
+    }, React.createElement(TextInput, {
+      isRequired: true,
+      type: "password",
+      id: "mail-password",
+      name: "mailPassword",
+      maxLength: 32,
+      value: fields.attributes.mailPassword || '',
+      onChange: value => this.setState({
+        errors: this.state.errors,
+        formFields: { ...this.state.formFields,
+          attributes: { ...this.state.formFields.attributes,
+            mailPassword: value
+          }
+        }
+      })
+    })), features.isInternationalizationEnabled && React.createElement(FormGroup, {
+      label: Msg.localize('selectLocale'),
+      isRequired: true,
+      fieldId: "locale"
+    }, React.createElement(LocaleSelector, {
+      id: "locale-selector",
+      value: fields.attributes.locale || '',
+      onChange: value => this.setState({
+        errors: this.state.errors,
+        formFields: { ...this.state.formFields,
+          attributes: { ...this.state.formFields.attributes,
+            locale: [value]
+          }
+        }
+      })
+    })), React.createElement(ActionGroup, null, React.createElement(Button, {
+      type: "submit",
+      id: "save-btn",
+      variant: "primary",
+      isDisabled: Object.values(this.state.errors).filter(e => e !== '').length !== 0
+    }, React.createElement(Msg, {
+      msgKey: "doSave"
+    })), React.createElement(Button, {
+      id: "cancel-btn",
+      variant: "secondary",
+      onClick: this.handleCancel
+    }, React.createElement(Msg, {
+      msgKey: "doCancel"
+    })))), this.isDeleteAccountAllowed && React.createElement("div", {
+      id: "delete-account",
+      style: {
+        marginTop: "30px"
+      }
+    }, React.createElement(Expandable, {
+      toggleText: "Delete Account"
+    }, React.createElement(Grid, {
+      gutter: "sm"
+    }, React.createElement(GridItem, {
+      span: 6
+    }, React.createElement("p", null, React.createElement(Msg, {
+      msgKey: "deleteAccountWarning"
+    }))), React.createElement(GridItem, {
+      span: 4
+    }, React.createElement(KeycloakContext.Consumer, null, keycloak => React.createElement(Button, {
+      id: "delete-account-btn",
+      variant: "danger",
+      onClick: () => this.handleDelete(keycloak),
+      className: "delete-button"
+    }, React.createElement(Msg, {
+      msgKey: "doDelete"
+    })))), React.createElement(GridItem, {
+      span: 2
+    })))));
+  }
+
+}
+
+_defineProperty(AccountPage, "contextType", AccountServiceContext);
+
+;
+//# sourceMappingURL=AccountPage.js.map
\ No newline at end of file
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/content/account-page/AccountPage.js.map b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/content/account-page/AccountPage.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..a747c50f804afd5c2eae9772b3c1f9c654227fbf
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/content/account-page/AccountPage.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../../../src/app/content/account-page/AccountPage.tsx"],"names":["React","ActionGroup","Button","Form","FormGroup","TextInput","Grid","GridItem","Expandable","AccountServiceContext","Msg","ContentPage","ContentAlert","LocaleSelector","KeycloakContext","AIACommand","AccountPage","Component","constructor","props","context","features","isRegistrationEmailAsUsername","isEditUserNameAllowed","deleteAccountAllowed","errors","username","firstName","lastName","email","formFields","attributes","DEFAULT_STATE","fetchPersonalInfo","value","event","target","currentTarget","name","setState","state","validationMessage","preventDefault","form","isValid","checkValidity","mailPass","mailPassword","getHash","then","res","reqData","doPost","success","locale","window","location","reload","formData","FormData","validationMessages","Array","from","keys","reduce","acc","key","elements","keycloak","execute","handleChange","doGet","response","data","password","doPost2","showMailPassField","awesome","tokenParsed","realm_access","roles","includes","render","fields","handleSubmit","localize","isInternationalizationEnabled","Object","values","filter","e","length","handleCancel","isDeleteAccountAllowed","marginTop","handleDelete"],"mappings":"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","sourcesContent":["/*\n * Copyright 2018 Red Hat, Inc. and/or its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport * as React from 'react';\nimport { ActionGroup, Button, Form, FormGroup, TextInput, Grid, GridItem, Expandable } from '@patternfly/react-core';\n\nimport { HttpResponse } from '../../account-service/account.service';\nimport { AccountServiceContext } from '../../account-service/AccountServiceContext';\nimport { Features } from '../../widgets/features';\nimport { Msg } from '../../widgets/Msg';\nimport { ContentPage } from '../ContentPage';\nimport { ContentAlert } from '../ContentAlert';\nimport { LocaleSelector } from '../../widgets/LocaleSelectors';\nimport { KeycloakContext } from '../../keycloak-service/KeycloakContext';\nimport { KeycloakClient, KeycloakService } from '../../keycloak-service/keycloak.service';\nimport { AIACommand } from '../../util/AIACommand';\n\ndeclare const features: Features;\ndeclare const locale: string;\ndeclare const keycloak: KeycloakClient;\n\n\ninterface AccountPageProps {\n}\n\ninterface FormFields {\n    readonly username?: string;\n    readonly firstName?: string;\n    readonly lastName?: string;\n    readonly email?: string;\n    attributes?: { locale?: [string], mailPassword?: string };\n}\n\ninterface AccountPageState {\n    readonly errors: FormFields;\n    readonly formFields: FormFields;\n}\n\n/**\n * @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.\n */\nexport class AccountPage extends React.Component<AccountPageProps, AccountPageState> {\n    static contextType = AccountServiceContext;\n    context: React.ContextType<typeof AccountServiceContext>;\n    private isRegistrationEmailAsUsername: boolean = features.isRegistrationEmailAsUsername;\n    private isEditUserNameAllowed: boolean = features.isEditUserNameAllowed;\n    private isDeleteAccountAllowed: boolean = features.deleteAccountAllowed;\n    private readonly DEFAULT_STATE: AccountPageState = {\n        errors: {\n            username: '',\n            firstName: '',\n            lastName: '',\n            email: ''\n        },\n        formFields: {\n            username: '',\n            firstName: '',\n            lastName: '',\n            email: '',\n            attributes: {}\n        }\n    };\n\n    public state: AccountPageState = this.DEFAULT_STATE;\n\n    public constructor(props: AccountPageProps, context: React.ContextType<typeof AccountServiceContext>) {\n        super(props);\n        this.context = context;\n\n        this.fetchPersonalInfo();\n    }\n\n    private fetchPersonalInfo(): void {\n        this.context!.doGet<FormFields>(\"/\")\n            .then((response: HttpResponse<FormFields>) => {\n                this.setState(this.DEFAULT_STATE);\n                const formFields = response.data;\n                if (!formFields!.attributes) {\n                    formFields!.attributes = { locale: [locale] };\n                }\n                else if (!formFields!.attributes.locale) {\n                    formFields!.attributes.locale = [locale];\n                }\n\n                this.setState({ ...{ formFields: formFields as FormFields } });\n            });\n    }\n\n    private handleCancel = (): void => {\n        this.fetchPersonalInfo();\n    }\n\n    private handleChange = (value: string, event: React.FormEvent<HTMLInputElement>) => {\n        const target = event.currentTarget;\n        const name = target.name;\n\n        this.setState({\n            errors: { ...this.state.errors, [name]: target.validationMessage },\n            formFields: { ...this.state.formFields, [name]: value }\n        });\n    }\n\n    private async getHash(value: string) {\n        let data = { password: value };\n        let response = await this.context!.doPost2<void>(\"/\", data);\n        return response;\n    }\n\n    private showMailPassField():boolean {\n        let awesome = keycloak.tokenParsed?.realm_access?.roles.includes(\"staff\") || false\n        return awesome;\n    }\n\n    private handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {\n        event.preventDefault();\n        const form = event.target as HTMLFormElement;\n        const isValid = form.checkValidity();\n        if (isValid) {\n\n            let mailPass = this.state.formFields.attributes!.mailPassword!\n            this.getHash(mailPass).then(res => {\n                this.setState({\n                    errors: this.state.errors,\n                    formFields: { ...this.state.formFields, attributes: { ...this.state.formFields.attributes, mailPassword: res } }\n                });\n\n                const reqData: FormFields = { ...this.state.formFields };\n                this.context!.doPost<void>(\"/\", reqData)\n                    .then(() => {\n                        ContentAlert.success('accountUpdatedMessage');\n                        if (locale !== this.state.formFields.attributes!.locale![0]) {\n                            window.location.reload();\n                        }\n\n                    })\n            });\n\n        } else {\n            const formData = new FormData(form);\n            const validationMessages = Array.from(formData.keys()).reduce((acc, key) => {\n                acc[key] = form.elements[key].validationMessage\n                return acc\n            }, {});\n            this.setState({\n                errors: { ...validationMessages },\n                formFields: this.state.formFields\n            });\n        }\n\n    }\n\n    private handleDelete = (keycloak: KeycloakService): void => {\n        new AIACommand(keycloak, \"delete_account\").execute();\n    }\n\n    public render(): React.ReactNode {\n        const fields: FormFields = this.state.formFields;\n        return (\n            <ContentPage title=\"personalInfoHtmlTitle\"\n                introMessage={this.showMailPassField() ? \"personalSubMessageAuth\" : \"personalSubMessage\"}>\n                <Form isHorizontal onSubmit={event => this.handleSubmit(event)}>\n                    {!this.isRegistrationEmailAsUsername &&\n                        <FormGroup\n                            label={Msg.localize('username')}\n                            isRequired\n                            fieldId=\"user-name\"\n                            helperTextInvalid={this.state.errors.username}\n                            isValid={this.state.errors.username === ''}\n                        >\n                            {this.isEditUserNameAllowed && <this.UsernameInput />}\n                            {!this.isEditUserNameAllowed && <this.RestrictedUsernameInput />}\n                        </FormGroup>\n                    }\n                    <FormGroup\n                        label={Msg.localize('email')}\n                        isRequired\n                        fieldId=\"email-address\"\n                        helperTextInvalid={this.state.errors.email}\n                        isValid={this.state.errors.email === ''}\n                    >\n                        <TextInput\n                            isRequired\n                            type=\"email\"\n                            id=\"email-address\"\n                            name=\"email\"\n                            maxLength={254}\n                            value={fields.email}\n                            onChange={this.handleChange}\n                            isValid={this.state.errors.email === ''}\n                        >\n                        </TextInput>\n                    </FormGroup>\n                    <FormGroup\n                        label={Msg.localize('firstName')}\n                        isRequired\n                        fieldId=\"first-name\"\n                        helperTextInvalid={this.state.errors.firstName}\n                        isValid={this.state.errors.firstName === ''}\n                    >\n                        <TextInput\n                            isRequired\n                            type=\"text\"\n                            id=\"first-name\"\n                            name=\"firstName\"\n                            maxLength={254}\n                            value={fields.firstName}\n                            onChange={this.handleChange}\n                            isValid={this.state.errors.firstName === ''}\n                        >\n                        </TextInput>\n                    </FormGroup>\n                    <FormGroup\n                        label={Msg.localize('lastName')}\n                        isRequired\n                        fieldId=\"last-name\"\n                        helperTextInvalid={this.state.errors.lastName}\n                        isValid={this.state.errors.lastName === ''}\n                    >\n                        <TextInput\n                            isRequired\n                            type=\"text\"\n                            id=\"last-name\"\n                            name=\"lastName\"\n                            maxLength={254}\n                            value={fields.lastName}\n                            onChange={this.handleChange}\n                            isValid={this.state.errors.lastName === ''}\n                        >\n                        </TextInput>\n                    </FormGroup>\n                    { this.showMailPassField() &&\n                    <FormGroup\n                        label={Msg.localize('mailPassword')}\n                        isRequired\n                        fieldId=\"mail-password\"\n                    >\n                        <TextInput\n                            isRequired\n                            type=\"password\"\n                            id=\"mail-password\"\n                            name=\"mailPassword\"\n                            maxLength={32}\n                            value={fields.attributes!.mailPassword || ''}\n                            onChange={value => this.setState({\n                                errors: this.state.errors,\n                                formFields: { ...this.state.formFields, attributes: { ...this.state.formFields.attributes, mailPassword: value } }\n                            })}\n                        >\n                        </TextInput>\n                    </FormGroup>}\n                    {features.isInternationalizationEnabled && <FormGroup\n                        label={Msg.localize('selectLocale')}\n                        isRequired\n                        fieldId=\"locale\"\n                    >\n                        <LocaleSelector id=\"locale-selector\"\n                            value={fields.attributes!.locale || ''}\n                            onChange={value => this.setState({\n                                errors: this.state.errors,\n                                formFields: { ...this.state.formFields, attributes: { ...this.state.formFields.attributes, locale: [value] } }\n                            })}\n                        />\n                    </FormGroup>}\n                    <ActionGroup>\n                        <Button\n                            type=\"submit\"\n                            id=\"save-btn\"\n                            variant=\"primary\"\n                            isDisabled={Object.values(this.state.errors).filter(e => e !== '').length !== 0}\n                        >\n                            <Msg msgKey=\"doSave\" />\n                        </Button>\n                        <Button\n                            id=\"cancel-btn\"\n                            variant=\"secondary\"\n                            onClick={this.handleCancel}\n                        >\n                            <Msg msgKey=\"doCancel\" />\n                        </Button>\n                    </ActionGroup>\n                </Form>\n\n                { this.isDeleteAccountAllowed &&\n                    <div id=\"delete-account\" style={{ marginTop: \"30px\" }}>\n                        <Expandable toggleText=\"Delete Account\">\n                            <Grid gutter={\"sm\"}>\n                                <GridItem span={6}>\n                                    <p>\n                                        <Msg msgKey=\"deleteAccountWarning\" />\n                                    </p>\n                                </GridItem>\n                                <GridItem span={4}>\n                                    <KeycloakContext.Consumer>\n                                        {(keycloak: KeycloakService) => (\n                                            <Button id=\"delete-account-btn\" variant=\"danger\" onClick={() => this.handleDelete(keycloak)} className=\"delete-button\"><Msg msgKey=\"doDelete\" /></Button>\n                                        )}\n                                    </KeycloakContext.Consumer>\n                                </GridItem>\n                                <GridItem span={2}>\n                                </GridItem>\n                            </Grid>\n\n                        </Expandable>\n                    </div>}\n            </ContentPage>\n        );\n    }\n\n    private UsernameInput = () => (\n        <TextInput\n            isRequired\n            type=\"text\"\n            id=\"user-name\"\n            name=\"username\"\n            maxLength={254}\n            value={this.state.formFields.username}\n            onChange={this.handleChange}\n            isValid={this.state.errors.username === ''}\n        >\n        </TextInput>\n    );\n\n    private RestrictedUsernameInput = () => (\n        <TextInput\n            isDisabled\n            type=\"text\"\n            id=\"user-name\"\n            name=\"username\"\n            value={this.state.formFields.username}\n        >\n        </TextInput>\n    );\n};\n"],"file":"AccountPage.js"}
\ No newline at end of file
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-favicon.ico b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..55497b852fc438a7a63041822a64deac8ad92527
Binary files /dev/null and b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-favicon.ico differ
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-logo-dark.svg b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-logo-dark.svg
new file mode 100644
index 0000000000000000000000000000000000000000..5a80cc4dcb8ffbe68c3ae1b058f88f1efddcf278
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-logo-dark.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.0"
+   width="600"
+   height="199.41692"
+   id="svg2424">
+  <defs
+     id="defs2426">
+    <linearGradient
+       x1="112.49854"
+       y1="6.1372099"
+       x2="112.49853"
+       y2="129.3468"
+       id="path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(287,-83)">
+      <stop
+         id="stop193"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop195"
+         style="stop-color:#ffffff;stop-opacity:0.27450982"
+         offset="1" />
+      <midPointStop
+         offset="0"
+         style="stop-color:#FFFFFF"
+         id="midPointStop197" />
+      <midPointStop
+         offset="0.5"
+         style="stop-color:#FFFFFF"
+         id="midPointStop199" />
+      <midPointStop
+         offset="1"
+         style="stop-color:#000000"
+         id="midPointStop201" />
+    </linearGradient>
+    <linearGradient
+       x1="541.33502"
+       y1="104.50665"
+       x2="606.91248"
+       y2="303.14029"
+       id="linearGradient2544"
+       xlink:href="#path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.3937741,0,0,0.393752,357.51969,122.00151)" />
+    <linearGradient
+       id="linearGradient3388">
+      <stop
+         id="stop3390"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop3392"
+         style="stop-color:#000000;stop-opacity:0.37113401"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="490.72305"
+       y1="237.72447"
+       x2="490.72305"
+       y2="183.9644"
+       id="linearGradient4416"
+       xlink:href="#linearGradient3388"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.749107,0,0,0.749107,-35.459862,91.44108)" />
+  </defs>
+  <g
+     transform="translate(-34.777313,-129.80241)"
+     id="layer1">
+    <g
+       transform="matrix(0.8746356,0,0,0.8746356,14.730518,23.408954)"
+       id="g2424">
+      <g
+         transform="matrix(0.6378586,0,0,0.6378586,36.486487,2.17139)"
+         id="g2809"
+         style="fill:#4d4d4d;fill-opacity:1">
+        <path
+           d="m 339.96875,309.09375 c -14.47141,-0.0239 -26.4812,2.94367 -31.125,4.5625 l -4.78125,25.8125 c -0.0116,0.0951 23.79543,-6.34855 34.28125,-5.96875 17.36158,0.62381 18.95948,6.63541 18.65625,14.75 0.29595,0.47462 -4.47933,-7.33192 -19.5,-7.59375 -18.94961,-0.32687 -45.69284,6.70947 -45.65625,35.3125 -0.51086,32.17412 24.03361,41.63882 40.75,41.8125 15.02821,-0.27364 22.0777,-5.69136 25.9375,-8.59375 5.07124,-5.30236 10.87308,-10.63447 16.40625,-17.03125 -5.23567,9.51278 -9.77472,16.0898 -14.5,21.125 l 0,4.25 22.84375,-3.84375 0.15625,-62.09375 c -0.23141,-8.78839 5.04123,-42.41827 -43.46875,-42.5 z m -3.28125,54.0625 c 9.46889,0.12995 20.32788,4.79708 20.34375,16.03125 0.049,10.21821 -12.80005,15.71183 -21.15625,15.625 -8.35976,-0.0868 -19.45093,-6.56982 -19.5,-16.53125 0.16016,-8.90444 10.45953,-15.35418 20.3125,-15.125 z"
+           id="path2284"
+           style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 398.50106,314.83145 -0.15505,102.82693 26.61213,-5.12724 0.0449,-58.30157 c 0.006,-8.68089 12.40554,-18.82451 27.9627,-18.66287 3.30202,-5.97408 9.5087,-21.24219 11.02088,-24.71514 -34.75649,-0.0833 -35.19897,9.98993 -41.24398,14.94517 -0.0631,-9.45285 -0.0213,-15.12741 -0.0213,-15.12741 l -24.2202,4.16213 z"
+           id="path2286"
+           style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 548.2688,328.33058 c -0.25696,-0.12068 -13.87938,-15.93419 -41.26638,-16.0589 -25.65249,-0.42638 -54.42578,9.51895 -54.88631,52.5328 0.22457,37.81852 27.6402,52.59809 55.0314,52.88627 29.31292,0.30451 40.97654,-18.32947 41.67615,-18.79124 -3.49762,-3.0321 -16.59792,-16.0131 -16.59792,-16.0131 0,0 -8.18236,11.65102 -24.05802,11.79913 -15.87942,0.1512 -29.68245,-12.27325 -29.87805,-29.60905 -0.20349,-17.33595 12.68881,-26.72821 29.99725,-27.48687 14.98466,-0.003 23.6297,9.67334 23.6297,9.67334 l 16.35218,-18.93238 z"
+           id="path2288"
+           style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 581.8125,278.84375 -25.125,5.90625 0.1875,133.9375 24.75,-4.46875 0.28125,-63.03125 c 0.0529,-6.60927 9.56127,-16.75916 25.4375,-16.4375 15.17973,0.15775 18.57236,10.11767 18.53125,11.375 l 0.4375,72.96875 24.40625,-4.3125 0.0937,-77.375 c 0.1607,-7.44539 -16.30833,-23.16954 -42.78125,-23.28125 -12.58087,0.0202 -19.54815,2.86825 -23.09375,4.96875 -6.06656,4.68565 -12.9998,9.17543 -19.8125,14.90625 6.29809,-8.09099 11.58551,-13.68516 16.75,-17.84375 l -0.0625,-37.3125 z"
+           id="path2290"
+           style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <g
+         transform="matrix(0.9443373,0,0.01336345,0.9443373,78.345657,-412.48879)"
+         id="g5326"
+         style="fill:#1793d1;fill-opacity:1;stroke:none">
+        <path
+           d="m 400.67581,629.79609 7.68167,-1.91575 -0.92851,91.20792 -7.79574,1.32426 1.04258,-90.61643 z"
+           id="path2292"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 421.10266,657.01757 6.75064,-2.9867 -0.86808,65.39931 -6.49779,1.33915 0.61523,-63.75176 z m -1.26059,-23.58316 5.47167,-4.41533 4.42261,4.99952 -5.47558,4.53221 -4.4187,-5.1164 z"
+           id="path2294"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 440.44273,655.82614 7.67755,-1.56201 -0.1573,13.6722 c -0.007,0.58717 4.4194,-15.27364 24.68502,-14.92094 19.67986,0.10952 22.68401,15.34634 22.5291,18.76237 l -0.43759,48.0783 -6.73044,1.45631 0.63316,-47.489 c 0.0974,-1.38684 -2.88144,-13.11441 -16.78906,-13.15754 -13.90509,-0.0404 -23.68364,10.10048 -23.75821,16.57937 l -0.48127,41.83477 -7.80388,2.0313 0.63292,-65.28513 z"
+           id="path2296"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 561.53301,720.20203 -7.6776,1.56186 0.15737,-13.67198 c 0.007,-0.58742 -4.42201,15.27361 -24.68504,14.92086 -19.67983,-0.10944 -22.68399,-15.34626 -22.52908,-18.76229 l 0.43757,-48.07861 8.15674,-1.64226 -0.54644,47.48988 c -0.0149,1.29682 1.36845,13.29979 15.27604,13.3426 13.90511,0.0405 23.76622,-8.37359 24.01453,-21.04416 l 0.43105,-37.46902 7.5978,-1.93195 -0.63294,65.28507 z"
+           id="path2298"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 577.45461,655.28678 -5.42715,4.20017 20.19894,26.93328 -22.39092,31.11622 5.63499,4.226 21.04365,-28.8967 20.8779,29.58159 5.32727,-4.20103 -22.37578,-31.62866 18.56963,-25.5775 -5.53193,-4.73429 -16.92109,23.66778 -19.00551,-24.68686 z"
+           id="path2300"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <path
+         d="m 105.8125,16.625 c -7.39687,18.135158 -11.858304,29.997682 -20.09375,47.59375 5.04936,5.35232 11.247211,11.585364 21.3125,18.625 C 96.210077,78.390904 88.828713,73.920352 83.3125,69.28125 72.7727,91.274163 56.259864,122.60209 22.75,182.8125 49.087628,167.60733 69.504089,158.23318 88.53125,154.65625 87.714216,151.1422 87.2497,147.34107 87.28125,143.375 l 0.03125,-0.84375 c 0.417917,-16.87382 9.195665,-29.84979 19.59375,-28.96875 10.39809,0.88104 18.48041,15.28242 18.0625,32.15625 -0.0786,3.17512 -0.43674,6.22955 -1.0625,9.0625 18.82058,3.68164 39.01873,13.03179 65,28.03125 -5.123,-9.4318 -9.69572,-17.93388 -14.0625,-26.03125 -6.87839,-5.33121 -14.05289,-12.2698 -28.6875,-19.78125 10.05899,2.61375 17.2611,5.62932 22.875,9 C 124.63297,63.338161 121.03766,52.354109 105.8125,16.625 z"
+         transform="matrix(1.1433333,0,0,1.1433333,22.920168,121.64318)"
+         id="path2518"
+         style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      <g
+         id="text2634"
+         style="font-size:8.44138241px;font-style:normal;font-weight:normal;fill:#1793d1;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 685.46692,263.83624 0,-5.32944 -1.99082,0 0,-0.71307 4.7895,0 0,0.71307 -1.99906,0 0,5.32944 -0.79962,0"
+           id="path3945"
+           style="fill:#1793d1;fill-opacity:1" />
+        <path
+           d="m 689.0982,263.83624 0,-6.04251 1.20355,0 1.43026,4.2784 c 0.13189,0.39843 0.22806,0.69658 0.28852,0.89442 0.0687,-0.21983 0.17586,-0.5427 0.3215,-0.96862 l 1.44674,-4.2042 1.07578,0 0,6.04251 -0.77077,0 0,-5.05741 -1.75587,5.05741 -0.72131,0 -1.74763,-5.14396 0,5.14396 -0.77077,0"
+           id="path3947"
+           style="fill:#1793d1;fill-opacity:1" />
+      </g>
+      <g
+         id="text2638"
+         style="font-size:8.25130367px;font-style:normal;font-weight:normal;fill:#1793d1;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 239.84053,313.69965 0,-5.20945 -1.94598,0 0,-0.697 4.68164,0 0,0.697 -1.95404,0 0,5.20945 -0.78162,0"
+           id="path3940"
+           style="fill:#1793d1;fill-opacity:1" />
+        <path
+           d="m 243.39004,313.69965 0,-5.90645 1.17646,0 1.39805,4.18205 c 0.12892,0.38947 0.22293,0.6809 0.28202,0.87429 0.0671,-0.21488 0.1719,-0.53048 0.31426,-0.94681 l 1.41417,-4.10953 1.05155,0 0,5.90645 -0.75341,0 0,-4.94353 -1.71634,4.94353 -0.70506,0 -1.70828,-5.02814 0,5.02814 -0.75342,0"
+           id="path3942"
+           style="fill:#1793d1;fill-opacity:1" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-logo-light.svg b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-logo-light.svg
new file mode 100644
index 0000000000000000000000000000000000000000..5fd0716fd855468528b2807136a434b94654c851
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/archlinux-logo-light.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.0"
+   width="600"
+   height="199.41692"
+   id="svg2424">
+  <defs
+     id="defs2426">
+    <linearGradient
+       x1="112.49854"
+       y1="6.1372099"
+       x2="112.49853"
+       y2="129.3468"
+       id="path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(287,-83)">
+      <stop
+         id="stop193"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop195"
+         style="stop-color:#ffffff;stop-opacity:0.27450982"
+         offset="1" />
+      <midPointStop
+         offset="0"
+         style="stop-color:#FFFFFF"
+         id="midPointStop197" />
+      <midPointStop
+         offset="0.5"
+         style="stop-color:#FFFFFF"
+         id="midPointStop199" />
+      <midPointStop
+         offset="1"
+         style="stop-color:#000000"
+         id="midPointStop201" />
+    </linearGradient>
+    <linearGradient
+       x1="541.33502"
+       y1="104.50665"
+       x2="606.91248"
+       y2="303.14029"
+       id="linearGradient2544"
+       xlink:href="#path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.3937741,0,0,0.393752,357.51969,122.00151)" />
+    <linearGradient
+       id="linearGradient3388">
+      <stop
+         id="stop3390"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop3392"
+         style="stop-color:#000000;stop-opacity:0.37113401"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="490.72305"
+       y1="237.72447"
+       x2="490.72305"
+       y2="183.9644"
+       id="linearGradient4416"
+       xlink:href="#linearGradient3388"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.749107,0,0,0.749107,-35.459862,91.44108)" />
+  </defs>
+  <g
+     transform="translate(-34.777313,-129.80241)"
+     id="layer1">
+    <g
+       transform="matrix(0.8746356,0,0,0.8746356,14.730518,23.408954)"
+       id="g2424">
+      <g
+         transform="matrix(0.6378586,0,0,0.6378586,36.486487,2.17139)"
+         id="g2809"
+         style="fill:#ffffff;fill-opacity:1">
+        <path
+           d="m 339.96875,309.09375 c -14.47141,-0.0239 -26.4812,2.94367 -31.125,4.5625 l -4.78125,25.8125 c -0.0116,0.0951 23.79543,-6.34855 34.28125,-5.96875 17.36158,0.62381 18.95948,6.63541 18.65625,14.75 0.29595,0.47462 -4.47933,-7.33192 -19.5,-7.59375 -18.94961,-0.32687 -45.69284,6.70947 -45.65625,35.3125 -0.51086,32.17412 24.03361,41.63882 40.75,41.8125 15.02821,-0.27364 22.0777,-5.69136 25.9375,-8.59375 5.07124,-5.30236 10.87308,-10.63447 16.40625,-17.03125 -5.23567,9.51278 -9.77472,16.0898 -14.5,21.125 l 0,4.25 22.84375,-3.84375 0.15625,-62.09375 c -0.23141,-8.78839 5.04123,-42.41827 -43.46875,-42.5 z m -3.28125,54.0625 c 9.46889,0.12995 20.32788,4.79708 20.34375,16.03125 0.049,10.21821 -12.80005,15.71183 -21.15625,15.625 -8.35976,-0.0868 -19.45093,-6.56982 -19.5,-16.53125 0.16016,-8.90444 10.45953,-15.35418 20.3125,-15.125 z"
+           id="path2284"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 398.50106,314.83145 -0.15505,102.82693 26.61213,-5.12724 0.0449,-58.30157 c 0.006,-8.68089 12.40554,-18.82451 27.9627,-18.66287 3.30202,-5.97408 9.5087,-21.24219 11.02088,-24.71514 -34.75649,-0.0833 -35.19897,9.98993 -41.24398,14.94517 -0.0631,-9.45285 -0.0213,-15.12741 -0.0213,-15.12741 l -24.2202,4.16213 z"
+           id="path2286"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 548.2688,328.33058 c -0.25696,-0.12068 -13.87938,-15.93419 -41.26638,-16.0589 -25.65249,-0.42638 -54.42578,9.51895 -54.88631,52.5328 0.22457,37.81852 27.6402,52.59809 55.0314,52.88627 29.31292,0.30451 40.97654,-18.32947 41.67615,-18.79124 -3.49762,-3.0321 -16.59792,-16.0131 -16.59792,-16.0131 0,0 -8.18236,11.65102 -24.05802,11.79913 -15.87942,0.1512 -29.68245,-12.27325 -29.87805,-29.60905 -0.20349,-17.33595 12.68881,-26.72821 29.99725,-27.48687 14.98466,-0.003 23.6297,9.67334 23.6297,9.67334 l 16.35218,-18.93238 z"
+           id="path2288"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 581.8125,278.84375 -25.125,5.90625 0.1875,133.9375 24.75,-4.46875 0.28125,-63.03125 c 0.0529,-6.60927 9.56127,-16.75916 25.4375,-16.4375 15.17973,0.15775 18.57236,10.11767 18.53125,11.375 l 0.4375,72.96875 24.40625,-4.3125 0.0937,-77.375 c 0.1607,-7.44539 -16.30833,-23.16954 -42.78125,-23.28125 -12.58087,0.0202 -19.54815,2.86825 -23.09375,4.96875 -6.06656,4.68565 -12.9998,9.17543 -19.8125,14.90625 6.29809,-8.09099 11.58551,-13.68516 16.75,-17.84375 l -0.0625,-37.3125 z"
+           id="path2290"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <g
+         transform="matrix(0.9443373,0,0.01336345,0.9443373,78.345657,-412.48879)"
+         id="g5326"
+         style="fill:#1793d1;fill-opacity:1;stroke:none">
+        <path
+           d="m 400.67581,629.79609 7.68167,-1.91575 -0.92851,91.20792 -7.79574,1.32426 1.04258,-90.61643 z"
+           id="path2292"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 421.10266,657.01757 6.75064,-2.9867 -0.86808,65.39931 -6.49779,1.33915 0.61523,-63.75176 z m -1.26059,-23.58316 5.47167,-4.41533 4.42261,4.99952 -5.47558,4.53221 -4.4187,-5.1164 z"
+           id="path2294"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 440.44273,655.82614 7.67755,-1.56201 -0.1573,13.6722 c -0.007,0.58717 4.4194,-15.27364 24.68502,-14.92094 19.67986,0.10952 22.68401,15.34634 22.5291,18.76237 l -0.43759,48.0783 -6.73044,1.45631 0.63316,-47.489 c 0.0974,-1.38684 -2.88144,-13.11441 -16.78906,-13.15754 -13.90509,-0.0404 -23.68364,10.10048 -23.75821,16.57937 l -0.48127,41.83477 -7.80388,2.0313 0.63292,-65.28513 z"
+           id="path2296"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 561.53301,720.20203 -7.6776,1.56186 0.15737,-13.67198 c 0.007,-0.58742 -4.42201,15.27361 -24.68504,14.92086 -19.67983,-0.10944 -22.68399,-15.34626 -22.52908,-18.76229 l 0.43757,-48.07861 8.15674,-1.64226 -0.54644,47.48988 c -0.0149,1.29682 1.36845,13.29979 15.27604,13.3426 13.90511,0.0405 23.76622,-8.37359 24.01453,-21.04416 l 0.43105,-37.46902 7.5978,-1.93195 -0.63294,65.28507 z"
+           id="path2298"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 577.45461,655.28678 -5.42715,4.20017 20.19894,26.93328 -22.39092,31.11622 5.63499,4.226 21.04365,-28.8967 20.8779,29.58159 5.32727,-4.20103 -22.37578,-31.62866 18.56963,-25.5775 -5.53193,-4.73429 -16.92109,23.66778 -19.00551,-24.68686 z"
+           id="path2300"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <path
+         d="m 105.8125,16.625 c -7.39687,18.135158 -11.858304,29.997682 -20.09375,47.59375 5.04936,5.35232 11.247211,11.585364 21.3125,18.625 C 96.210077,78.390904 88.828713,73.920352 83.3125,69.28125 72.7727,91.274163 56.259864,122.60209 22.75,182.8125 49.087628,167.60733 69.504089,158.23318 88.53125,154.65625 87.714216,151.1422 87.2497,147.34107 87.28125,143.375 l 0.03125,-0.84375 c 0.417917,-16.87382 9.195665,-29.84979 19.59375,-28.96875 10.39809,0.88104 18.48041,15.28242 18.0625,32.15625 -0.0786,3.17512 -0.43674,6.22955 -1.0625,9.0625 18.82058,3.68164 39.01873,13.03179 65,28.03125 -5.123,-9.4318 -9.69572,-17.93388 -14.0625,-26.03125 -6.87839,-5.33121 -14.05289,-12.2698 -28.6875,-19.78125 10.05899,2.61375 17.2611,5.62932 22.875,9 C 124.63297,63.338161 121.03766,52.354109 105.8125,16.625 z"
+         transform="matrix(1.1433333,0,0,1.1433333,22.920168,121.64318)"
+         id="path2518"
+         style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      <g
+         id="text2634"
+         style="font-size:8.44138241px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 685.46692,263.83624 0,-5.32944 -1.99082,0 0,-0.71307 4.7895,0 0,0.71307 -1.99906,0 0,5.32944 -0.79962,0"
+           id="path3660"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 689.0982,263.83624 0,-6.04251 1.20355,0 1.43026,4.2784 c 0.13189,0.39843 0.22806,0.69658 0.28852,0.89442 0.0687,-0.21983 0.17586,-0.5427 0.3215,-0.96862 l 1.44674,-4.2042 1.07578,0 0,6.04251 -0.77077,0 0,-5.05741 -1.75587,5.05741 -0.72131,0 -1.74763,-5.14396 0,5.14396 -0.77077,0"
+           id="path3662"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+      <g
+         id="text2638"
+         style="font-size:8.25130367px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 239.84053,313.69965 0,-5.20945 -1.94598,0 0,-0.697 4.68164,0 0,0.697 -1.95404,0 0,5.20945 -0.78162,0"
+           id="path2883"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 243.39004,313.69965 0,-5.90645 1.17646,0 1.39805,4.18205 c 0.12892,0.38947 0.22293,0.6809 0.28202,0.87429 0.0671,-0.21488 0.1719,-0.53048 0.31426,-0.94681 l 1.41417,-4.10953 1.05155,0 0,5.90645 -0.75341,0 0,-4.94353 -1.71634,4.94353 -0.70506,0 -1.70828,-5.02814 0,5.02814 -0.75342,0"
+           id="path2885"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/layout.css b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/layout.css
new file mode 100644
index 0000000000000000000000000000000000000000..4b059a10853154a235a1eb0c6a8154775b7b5832
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/resources/public/layout.css
@@ -0,0 +1,3 @@
+.brand {
+  height: 50px;
+}
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/theme.properties b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/theme.properties
new file mode 100644
index 0000000000000000000000000000000000000000..5fff4b5eb951cfe522b6ca4c48de6c3918452dc5
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/account/theme.properties
@@ -0,0 +1,4 @@
+parent=keycloak.v2
+logo=/public/archlinux-logo-light.svg
+logoDark=/public/archlinux-logo-dark.svg
+favIcon=/public/archlinux-favicon.ico
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/resources/css/custom.css b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/resources/css/custom.css
new file mode 100644
index 0000000000000000000000000000000000000000..54c49a77f139369863fac4abefa41ac2b985bbce
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/resources/css/custom.css
@@ -0,0 +1,7 @@
+@import 'styles.css';
+
+.navbar-pf .navbar-brand {
+    background-image: url('../img/archlinux-logo-light.svg');
+    background-size: 150px 50px;
+    width: 150px;
+}
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/resources/img/archlinux-logo-light.svg b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/resources/img/archlinux-logo-light.svg
new file mode 100644
index 0000000000000000000000000000000000000000..5fd0716fd855468528b2807136a434b94654c851
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/resources/img/archlinux-logo-light.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.0"
+   width="600"
+   height="199.41692"
+   id="svg2424">
+  <defs
+     id="defs2426">
+    <linearGradient
+       x1="112.49854"
+       y1="6.1372099"
+       x2="112.49853"
+       y2="129.3468"
+       id="path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(287,-83)">
+      <stop
+         id="stop193"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop195"
+         style="stop-color:#ffffff;stop-opacity:0.27450982"
+         offset="1" />
+      <midPointStop
+         offset="0"
+         style="stop-color:#FFFFFF"
+         id="midPointStop197" />
+      <midPointStop
+         offset="0.5"
+         style="stop-color:#FFFFFF"
+         id="midPointStop199" />
+      <midPointStop
+         offset="1"
+         style="stop-color:#000000"
+         id="midPointStop201" />
+    </linearGradient>
+    <linearGradient
+       x1="541.33502"
+       y1="104.50665"
+       x2="606.91248"
+       y2="303.14029"
+       id="linearGradient2544"
+       xlink:href="#path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.3937741,0,0,0.393752,357.51969,122.00151)" />
+    <linearGradient
+       id="linearGradient3388">
+      <stop
+         id="stop3390"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop3392"
+         style="stop-color:#000000;stop-opacity:0.37113401"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="490.72305"
+       y1="237.72447"
+       x2="490.72305"
+       y2="183.9644"
+       id="linearGradient4416"
+       xlink:href="#linearGradient3388"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.749107,0,0,0.749107,-35.459862,91.44108)" />
+  </defs>
+  <g
+     transform="translate(-34.777313,-129.80241)"
+     id="layer1">
+    <g
+       transform="matrix(0.8746356,0,0,0.8746356,14.730518,23.408954)"
+       id="g2424">
+      <g
+         transform="matrix(0.6378586,0,0,0.6378586,36.486487,2.17139)"
+         id="g2809"
+         style="fill:#ffffff;fill-opacity:1">
+        <path
+           d="m 339.96875,309.09375 c -14.47141,-0.0239 -26.4812,2.94367 -31.125,4.5625 l -4.78125,25.8125 c -0.0116,0.0951 23.79543,-6.34855 34.28125,-5.96875 17.36158,0.62381 18.95948,6.63541 18.65625,14.75 0.29595,0.47462 -4.47933,-7.33192 -19.5,-7.59375 -18.94961,-0.32687 -45.69284,6.70947 -45.65625,35.3125 -0.51086,32.17412 24.03361,41.63882 40.75,41.8125 15.02821,-0.27364 22.0777,-5.69136 25.9375,-8.59375 5.07124,-5.30236 10.87308,-10.63447 16.40625,-17.03125 -5.23567,9.51278 -9.77472,16.0898 -14.5,21.125 l 0,4.25 22.84375,-3.84375 0.15625,-62.09375 c -0.23141,-8.78839 5.04123,-42.41827 -43.46875,-42.5 z m -3.28125,54.0625 c 9.46889,0.12995 20.32788,4.79708 20.34375,16.03125 0.049,10.21821 -12.80005,15.71183 -21.15625,15.625 -8.35976,-0.0868 -19.45093,-6.56982 -19.5,-16.53125 0.16016,-8.90444 10.45953,-15.35418 20.3125,-15.125 z"
+           id="path2284"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 398.50106,314.83145 -0.15505,102.82693 26.61213,-5.12724 0.0449,-58.30157 c 0.006,-8.68089 12.40554,-18.82451 27.9627,-18.66287 3.30202,-5.97408 9.5087,-21.24219 11.02088,-24.71514 -34.75649,-0.0833 -35.19897,9.98993 -41.24398,14.94517 -0.0631,-9.45285 -0.0213,-15.12741 -0.0213,-15.12741 l -24.2202,4.16213 z"
+           id="path2286"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 548.2688,328.33058 c -0.25696,-0.12068 -13.87938,-15.93419 -41.26638,-16.0589 -25.65249,-0.42638 -54.42578,9.51895 -54.88631,52.5328 0.22457,37.81852 27.6402,52.59809 55.0314,52.88627 29.31292,0.30451 40.97654,-18.32947 41.67615,-18.79124 -3.49762,-3.0321 -16.59792,-16.0131 -16.59792,-16.0131 0,0 -8.18236,11.65102 -24.05802,11.79913 -15.87942,0.1512 -29.68245,-12.27325 -29.87805,-29.60905 -0.20349,-17.33595 12.68881,-26.72821 29.99725,-27.48687 14.98466,-0.003 23.6297,9.67334 23.6297,9.67334 l 16.35218,-18.93238 z"
+           id="path2288"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 581.8125,278.84375 -25.125,5.90625 0.1875,133.9375 24.75,-4.46875 0.28125,-63.03125 c 0.0529,-6.60927 9.56127,-16.75916 25.4375,-16.4375 15.17973,0.15775 18.57236,10.11767 18.53125,11.375 l 0.4375,72.96875 24.40625,-4.3125 0.0937,-77.375 c 0.1607,-7.44539 -16.30833,-23.16954 -42.78125,-23.28125 -12.58087,0.0202 -19.54815,2.86825 -23.09375,4.96875 -6.06656,4.68565 -12.9998,9.17543 -19.8125,14.90625 6.29809,-8.09099 11.58551,-13.68516 16.75,-17.84375 l -0.0625,-37.3125 z"
+           id="path2290"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <g
+         transform="matrix(0.9443373,0,0.01336345,0.9443373,78.345657,-412.48879)"
+         id="g5326"
+         style="fill:#1793d1;fill-opacity:1;stroke:none">
+        <path
+           d="m 400.67581,629.79609 7.68167,-1.91575 -0.92851,91.20792 -7.79574,1.32426 1.04258,-90.61643 z"
+           id="path2292"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 421.10266,657.01757 6.75064,-2.9867 -0.86808,65.39931 -6.49779,1.33915 0.61523,-63.75176 z m -1.26059,-23.58316 5.47167,-4.41533 4.42261,4.99952 -5.47558,4.53221 -4.4187,-5.1164 z"
+           id="path2294"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 440.44273,655.82614 7.67755,-1.56201 -0.1573,13.6722 c -0.007,0.58717 4.4194,-15.27364 24.68502,-14.92094 19.67986,0.10952 22.68401,15.34634 22.5291,18.76237 l -0.43759,48.0783 -6.73044,1.45631 0.63316,-47.489 c 0.0974,-1.38684 -2.88144,-13.11441 -16.78906,-13.15754 -13.90509,-0.0404 -23.68364,10.10048 -23.75821,16.57937 l -0.48127,41.83477 -7.80388,2.0313 0.63292,-65.28513 z"
+           id="path2296"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 561.53301,720.20203 -7.6776,1.56186 0.15737,-13.67198 c 0.007,-0.58742 -4.42201,15.27361 -24.68504,14.92086 -19.67983,-0.10944 -22.68399,-15.34626 -22.52908,-18.76229 l 0.43757,-48.07861 8.15674,-1.64226 -0.54644,47.48988 c -0.0149,1.29682 1.36845,13.29979 15.27604,13.3426 13.90511,0.0405 23.76622,-8.37359 24.01453,-21.04416 l 0.43105,-37.46902 7.5978,-1.93195 -0.63294,65.28507 z"
+           id="path2298"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 577.45461,655.28678 -5.42715,4.20017 20.19894,26.93328 -22.39092,31.11622 5.63499,4.226 21.04365,-28.8967 20.8779,29.58159 5.32727,-4.20103 -22.37578,-31.62866 18.56963,-25.5775 -5.53193,-4.73429 -16.92109,23.66778 -19.00551,-24.68686 z"
+           id="path2300"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <path
+         d="m 105.8125,16.625 c -7.39687,18.135158 -11.858304,29.997682 -20.09375,47.59375 5.04936,5.35232 11.247211,11.585364 21.3125,18.625 C 96.210077,78.390904 88.828713,73.920352 83.3125,69.28125 72.7727,91.274163 56.259864,122.60209 22.75,182.8125 49.087628,167.60733 69.504089,158.23318 88.53125,154.65625 87.714216,151.1422 87.2497,147.34107 87.28125,143.375 l 0.03125,-0.84375 c 0.417917,-16.87382 9.195665,-29.84979 19.59375,-28.96875 10.39809,0.88104 18.48041,15.28242 18.0625,32.15625 -0.0786,3.17512 -0.43674,6.22955 -1.0625,9.0625 18.82058,3.68164 39.01873,13.03179 65,28.03125 -5.123,-9.4318 -9.69572,-17.93388 -14.0625,-26.03125 -6.87839,-5.33121 -14.05289,-12.2698 -28.6875,-19.78125 10.05899,2.61375 17.2611,5.62932 22.875,9 C 124.63297,63.338161 121.03766,52.354109 105.8125,16.625 z"
+         transform="matrix(1.1433333,0,0,1.1433333,22.920168,121.64318)"
+         id="path2518"
+         style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      <g
+         id="text2634"
+         style="font-size:8.44138241px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 685.46692,263.83624 0,-5.32944 -1.99082,0 0,-0.71307 4.7895,0 0,0.71307 -1.99906,0 0,5.32944 -0.79962,0"
+           id="path3660"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 689.0982,263.83624 0,-6.04251 1.20355,0 1.43026,4.2784 c 0.13189,0.39843 0.22806,0.69658 0.28852,0.89442 0.0687,-0.21983 0.17586,-0.5427 0.3215,-0.96862 l 1.44674,-4.2042 1.07578,0 0,6.04251 -0.77077,0 0,-5.05741 -1.75587,5.05741 -0.72131,0 -1.74763,-5.14396 0,5.14396 -0.77077,0"
+           id="path3662"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+      <g
+         id="text2638"
+         style="font-size:8.25130367px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 239.84053,313.69965 0,-5.20945 -1.94598,0 0,-0.697 4.68164,0 0,0.697 -1.95404,0 0,5.20945 -0.78162,0"
+           id="path2883"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 243.39004,313.69965 0,-5.90645 1.17646,0 1.39805,4.18205 c 0.12892,0.38947 0.22293,0.6809 0.28202,0.87429 0.0671,-0.21488 0.1719,-0.53048 0.31426,-0.94681 l 1.41417,-4.10953 1.05155,0 0,5.90645 -0.75341,0 0,-4.94353 -1.71634,4.94353 -0.70506,0 -1.70828,-5.02814 0,5.02814 -0.75342,0"
+           id="path2885"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/theme.properties b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/theme.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ff5778df76922c344600c8644acefa9458e4a74e
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/admin/theme.properties
@@ -0,0 +1,2 @@
+parent=keycloak
+styles=css/custom.css
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/login-config-totp.ftl b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/login-config-totp.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..a7cd43885b30cba59f3bb25d39113677ed95084a
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/login-config-totp.ftl
@@ -0,0 +1,111 @@
+<#import "template.ftl" as layout>
+<@layout.registrationLayout displayInfo=true displayRequiredFields=true; section>
+
+    <#if section = "header">
+        ${msg("loginTotpTitle")}
+
+    <#elseif section = "form">
+
+    <div class="alert alert-warning">
+    <span class="${properties.kcFeedbackWarningIcon}"></span>
+    ${kcSanitize(msg("totp-registration-warning"))?no_esc}
+    </div>
+
+    <ol id="kc-totp-settings">
+        <li>
+            <p>${msg("loginTotpStep1")}</p>
+
+            <ul id="kc-totp-supported-apps">
+                <div style="margin-bottom: 10px; float: left; width: 40%">
+                    <h4>Android</h4>
+                    <ul style="margin-top: -5px;">
+                        <li><a target="_blank" rel="noopener noreferrer" href="https://getaegis.app/">Aegis</a></li>
+                        <li><a target="_blank" rel="noopener noreferrer" href="https://github.com/andOTP/andOTP">andOTP</a></li>
+                        <li><a target="_blank" rel="noopener noreferrer" href="https://github.com/helloworld1/FreeOTPPlus">FreeOTP+</a></li>
+                    </ul>
+                </div>
+                <div style="margin-bottom: 10px; float: left; width: 60%">
+                    <h4>iOS</h4>
+                    <ul style="margin-top: -5px;">
+                        <li><a target="_blank" rel="noopener noreferrer" href="https://authy.com/">Authy</a></li>
+                        <li><a target="_blank" rel="noopener noreferrer" href="https://lastpass.com/auth/">LastPass Authenticator</a></li>
+                        <li><a target="_blank" rel="noopener noreferrer" href="https://cooperrs.de/otpauth.html ">OTP Auth</a></li>
+                    </ul>
+                </div>
+            </ul>
+        </li>
+
+        <#if mode?? && mode = "manual">
+            <li>
+                <p>${msg("loginTotpManualStep2")}</p>
+                <p><span id="kc-totp-secret-key">${totp.totpSecretEncoded}</span></p>
+                <p><a href="${totp.qrUrl}" id="mode-barcode">${msg("loginTotpScanBarcode")}</a></p>
+            </li>
+            <li>
+                <p>${msg("loginTotpManualStep3")}</p>
+                <p>
+                    <ul>
+                        <li id="kc-totp-type">${msg("loginTotpType")}: ${msg("loginTotp." + totp.policy.type)}</li>
+                        <li id="kc-totp-algorithm">${msg("loginTotpAlgorithm")}: ${totp.policy.getAlgorithmKey()}</li>
+                        <li id="kc-totp-digits">${msg("loginTotpDigits")}: ${totp.policy.digits}</li>
+                        <#if totp.policy.type = "totp">
+                            <li id="kc-totp-period">${msg("loginTotpInterval")}: ${totp.policy.period}</li>
+                        <#elseif totp.policy.type = "hotp">
+                            <li id="kc-totp-counter">${msg("loginTotpCounter")}: ${totp.policy.initialCounter}</li>
+                        </#if>
+                    </ul>
+                </p>
+            </li>
+        <#else>
+            <li>
+                <p>${msg("loginTotpStep2")}</p>
+                <img id="kc-totp-secret-qr-code" src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"><br/>
+                <p><a href="${totp.manualUrl}" id="mode-manual">${msg("loginTotpUnableToScan")}</a></p>
+            </li>
+        </#if>
+        <li>
+            <p>${msg("loginTotpStep3")}</p>
+            <p>${msg("loginTotpStep3DeviceName")}</p>
+        </li>
+    </ol>
+
+    <form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-totp-settings-form" method="post">
+        <div class="${properties.kcFormGroupClass!}">
+            <div class="${properties.kcInputWrapperClass!}">
+                <label for="totp" class="control-label">${msg("authenticatorCode")}</label> <span class="required">*</span>
+            </div>
+            <div class="${properties.kcInputWrapperClass!}">
+                <input type="text" id="totp" name="totp" autocomplete="off" class="${properties.kcInputClass!}" />
+            </div>
+            <input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}" />
+            <#if mode??><input type="hidden" id="mode" name="mode" value="${mode}"/></#if>
+        </div>
+
+        <div class="${properties.kcFormGroupClass!}" ${messagesPerField.printIfExists('userLabel',properties.kcFormGroupErrorClass!)}">
+            <div class="${properties.kcInputWrapperClass!}">
+                <label for="userLabel" class="control-label">${msg("loginTotpDeviceName")}</label> <#if totp.otpCredentials?size gte 1><span class="required">*</span></#if>
+            </div>
+
+            <div class="${properties.kcInputWrapperClass!}">
+                <input type="text" class="form-control" id="userLabel" name="userLabel" autocomplete="off">
+            </div>
+        </div>
+
+        <#if isAppInitiatedAction??>
+            <input type="submit"
+                   class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
+                   id="saveTOTPBtn" value="${msg("doSubmit")}"
+            />
+            <button type="submit"
+                    class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!} ${properties.kcButtonLargeClass!}"
+                    id="cancelTOTPBtn" name="cancel-aia" value="true" />${msg("doCancel")}
+            </button>
+        <#else>
+            <input type="submit"
+                   class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
+                   id="saveTOTPBtn" value="${msg("doSubmit")}"
+            />
+        </#if>
+    </form>
+    </#if>
+</@layout.registrationLayout>
\ No newline at end of file
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/messages/messages_en.properties b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/messages/messages_en.properties
new file mode 100644
index 0000000000000000000000000000000000000000..981bef18ac0478fa81fd4c60afab48a1d4b3a7c9
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/messages/messages_en.properties
@@ -0,0 +1,3 @@
+configureTotpMessage=<p>You need to set up a Mobile Authenticator to activate your account.</p>
+totp-registration-warning=<p><strong>Warning</strong>: For security reasons, we may not be able to restore access to accounts with two-factor authentication enabled if you lose your two-factor authentication credentials. For this reason, it is highly recommended that you <strong>backup your credentials</strong>.</p>
+webauthn-registration-warning=<p><strong>Warning</strong>: For security reasons, we may not be able to restore access to accounts with two-factor authentication enabled if you lose your two-factor authentication device. For this reason, it is highly recommended that you also set up a TOTP authenticator on top of your WebAuthn device (or a second WebAuthn device) in order to have an additional login method in place. This can be done from your account page.</p>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/css/custom.css b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/css/custom.css
new file mode 100644
index 0000000000000000000000000000000000000000..f09e957f73ffbaacd8833d40ee5d15ccdb4c0ae8
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/css/custom.css
@@ -0,0 +1,26 @@
+@import 'login.css';
+
+.login-pf body {
+    background: url("../img/login-background.jpg") no-repeat center center fixed;
+    background-size: cover;
+}
+
+html.login-pf {
+    background: url("../img/login-background.jpg") no-repeat center center fixed;
+    background-size: cover;
+}
+
+div.kc-logo-text {
+    background-image: url('../img/archlinux-logo-light.svg');
+    background-size: 100%;
+    height: 100px;
+}
+
+@media(max-width: 767px) {
+    div.kc-logo-text {
+        background-size: 100%;
+        height: 60px;
+        width: 200px;
+        margin: 0 auto;
+    }
+}
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/img/archlinux-logo-light.svg b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/img/archlinux-logo-light.svg
new file mode 100644
index 0000000000000000000000000000000000000000..5fd0716fd855468528b2807136a434b94654c851
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/img/archlinux-logo-light.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.0"
+   width="600"
+   height="199.41692"
+   id="svg2424">
+  <defs
+     id="defs2426">
+    <linearGradient
+       x1="112.49854"
+       y1="6.1372099"
+       x2="112.49853"
+       y2="129.3468"
+       id="path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(287,-83)">
+      <stop
+         id="stop193"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop195"
+         style="stop-color:#ffffff;stop-opacity:0.27450982"
+         offset="1" />
+      <midPointStop
+         offset="0"
+         style="stop-color:#FFFFFF"
+         id="midPointStop197" />
+      <midPointStop
+         offset="0.5"
+         style="stop-color:#FFFFFF"
+         id="midPointStop199" />
+      <midPointStop
+         offset="1"
+         style="stop-color:#000000"
+         id="midPointStop201" />
+    </linearGradient>
+    <linearGradient
+       x1="541.33502"
+       y1="104.50665"
+       x2="606.91248"
+       y2="303.14029"
+       id="linearGradient2544"
+       xlink:href="#path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.3937741,0,0,0.393752,357.51969,122.00151)" />
+    <linearGradient
+       id="linearGradient3388">
+      <stop
+         id="stop3390"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop3392"
+         style="stop-color:#000000;stop-opacity:0.37113401"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="490.72305"
+       y1="237.72447"
+       x2="490.72305"
+       y2="183.9644"
+       id="linearGradient4416"
+       xlink:href="#linearGradient3388"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.749107,0,0,0.749107,-35.459862,91.44108)" />
+  </defs>
+  <g
+     transform="translate(-34.777313,-129.80241)"
+     id="layer1">
+    <g
+       transform="matrix(0.8746356,0,0,0.8746356,14.730518,23.408954)"
+       id="g2424">
+      <g
+         transform="matrix(0.6378586,0,0,0.6378586,36.486487,2.17139)"
+         id="g2809"
+         style="fill:#ffffff;fill-opacity:1">
+        <path
+           d="m 339.96875,309.09375 c -14.47141,-0.0239 -26.4812,2.94367 -31.125,4.5625 l -4.78125,25.8125 c -0.0116,0.0951 23.79543,-6.34855 34.28125,-5.96875 17.36158,0.62381 18.95948,6.63541 18.65625,14.75 0.29595,0.47462 -4.47933,-7.33192 -19.5,-7.59375 -18.94961,-0.32687 -45.69284,6.70947 -45.65625,35.3125 -0.51086,32.17412 24.03361,41.63882 40.75,41.8125 15.02821,-0.27364 22.0777,-5.69136 25.9375,-8.59375 5.07124,-5.30236 10.87308,-10.63447 16.40625,-17.03125 -5.23567,9.51278 -9.77472,16.0898 -14.5,21.125 l 0,4.25 22.84375,-3.84375 0.15625,-62.09375 c -0.23141,-8.78839 5.04123,-42.41827 -43.46875,-42.5 z m -3.28125,54.0625 c 9.46889,0.12995 20.32788,4.79708 20.34375,16.03125 0.049,10.21821 -12.80005,15.71183 -21.15625,15.625 -8.35976,-0.0868 -19.45093,-6.56982 -19.5,-16.53125 0.16016,-8.90444 10.45953,-15.35418 20.3125,-15.125 z"
+           id="path2284"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 398.50106,314.83145 -0.15505,102.82693 26.61213,-5.12724 0.0449,-58.30157 c 0.006,-8.68089 12.40554,-18.82451 27.9627,-18.66287 3.30202,-5.97408 9.5087,-21.24219 11.02088,-24.71514 -34.75649,-0.0833 -35.19897,9.98993 -41.24398,14.94517 -0.0631,-9.45285 -0.0213,-15.12741 -0.0213,-15.12741 l -24.2202,4.16213 z"
+           id="path2286"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 548.2688,328.33058 c -0.25696,-0.12068 -13.87938,-15.93419 -41.26638,-16.0589 -25.65249,-0.42638 -54.42578,9.51895 -54.88631,52.5328 0.22457,37.81852 27.6402,52.59809 55.0314,52.88627 29.31292,0.30451 40.97654,-18.32947 41.67615,-18.79124 -3.49762,-3.0321 -16.59792,-16.0131 -16.59792,-16.0131 0,0 -8.18236,11.65102 -24.05802,11.79913 -15.87942,0.1512 -29.68245,-12.27325 -29.87805,-29.60905 -0.20349,-17.33595 12.68881,-26.72821 29.99725,-27.48687 14.98466,-0.003 23.6297,9.67334 23.6297,9.67334 l 16.35218,-18.93238 z"
+           id="path2288"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 581.8125,278.84375 -25.125,5.90625 0.1875,133.9375 24.75,-4.46875 0.28125,-63.03125 c 0.0529,-6.60927 9.56127,-16.75916 25.4375,-16.4375 15.17973,0.15775 18.57236,10.11767 18.53125,11.375 l 0.4375,72.96875 24.40625,-4.3125 0.0937,-77.375 c 0.1607,-7.44539 -16.30833,-23.16954 -42.78125,-23.28125 -12.58087,0.0202 -19.54815,2.86825 -23.09375,4.96875 -6.06656,4.68565 -12.9998,9.17543 -19.8125,14.90625 6.29809,-8.09099 11.58551,-13.68516 16.75,-17.84375 l -0.0625,-37.3125 z"
+           id="path2290"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <g
+         transform="matrix(0.9443373,0,0.01336345,0.9443373,78.345657,-412.48879)"
+         id="g5326"
+         style="fill:#1793d1;fill-opacity:1;stroke:none">
+        <path
+           d="m 400.67581,629.79609 7.68167,-1.91575 -0.92851,91.20792 -7.79574,1.32426 1.04258,-90.61643 z"
+           id="path2292"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 421.10266,657.01757 6.75064,-2.9867 -0.86808,65.39931 -6.49779,1.33915 0.61523,-63.75176 z m -1.26059,-23.58316 5.47167,-4.41533 4.42261,4.99952 -5.47558,4.53221 -4.4187,-5.1164 z"
+           id="path2294"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 440.44273,655.82614 7.67755,-1.56201 -0.1573,13.6722 c -0.007,0.58717 4.4194,-15.27364 24.68502,-14.92094 19.67986,0.10952 22.68401,15.34634 22.5291,18.76237 l -0.43759,48.0783 -6.73044,1.45631 0.63316,-47.489 c 0.0974,-1.38684 -2.88144,-13.11441 -16.78906,-13.15754 -13.90509,-0.0404 -23.68364,10.10048 -23.75821,16.57937 l -0.48127,41.83477 -7.80388,2.0313 0.63292,-65.28513 z"
+           id="path2296"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 561.53301,720.20203 -7.6776,1.56186 0.15737,-13.67198 c 0.007,-0.58742 -4.42201,15.27361 -24.68504,14.92086 -19.67983,-0.10944 -22.68399,-15.34626 -22.52908,-18.76229 l 0.43757,-48.07861 8.15674,-1.64226 -0.54644,47.48988 c -0.0149,1.29682 1.36845,13.29979 15.27604,13.3426 13.90511,0.0405 23.76622,-8.37359 24.01453,-21.04416 l 0.43105,-37.46902 7.5978,-1.93195 -0.63294,65.28507 z"
+           id="path2298"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 577.45461,655.28678 -5.42715,4.20017 20.19894,26.93328 -22.39092,31.11622 5.63499,4.226 21.04365,-28.8967 20.8779,29.58159 5.32727,-4.20103 -22.37578,-31.62866 18.56963,-25.5775 -5.53193,-4.73429 -16.92109,23.66778 -19.00551,-24.68686 z"
+           id="path2300"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <path
+         d="m 105.8125,16.625 c -7.39687,18.135158 -11.858304,29.997682 -20.09375,47.59375 5.04936,5.35232 11.247211,11.585364 21.3125,18.625 C 96.210077,78.390904 88.828713,73.920352 83.3125,69.28125 72.7727,91.274163 56.259864,122.60209 22.75,182.8125 49.087628,167.60733 69.504089,158.23318 88.53125,154.65625 87.714216,151.1422 87.2497,147.34107 87.28125,143.375 l 0.03125,-0.84375 c 0.417917,-16.87382 9.195665,-29.84979 19.59375,-28.96875 10.39809,0.88104 18.48041,15.28242 18.0625,32.15625 -0.0786,3.17512 -0.43674,6.22955 -1.0625,9.0625 18.82058,3.68164 39.01873,13.03179 65,28.03125 -5.123,-9.4318 -9.69572,-17.93388 -14.0625,-26.03125 -6.87839,-5.33121 -14.05289,-12.2698 -28.6875,-19.78125 10.05899,2.61375 17.2611,5.62932 22.875,9 C 124.63297,63.338161 121.03766,52.354109 105.8125,16.625 z"
+         transform="matrix(1.1433333,0,0,1.1433333,22.920168,121.64318)"
+         id="path2518"
+         style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      <g
+         id="text2634"
+         style="font-size:8.44138241px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 685.46692,263.83624 0,-5.32944 -1.99082,0 0,-0.71307 4.7895,0 0,0.71307 -1.99906,0 0,5.32944 -0.79962,0"
+           id="path3660"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 689.0982,263.83624 0,-6.04251 1.20355,0 1.43026,4.2784 c 0.13189,0.39843 0.22806,0.69658 0.28852,0.89442 0.0687,-0.21983 0.17586,-0.5427 0.3215,-0.96862 l 1.44674,-4.2042 1.07578,0 0,6.04251 -0.77077,0 0,-5.05741 -1.75587,5.05741 -0.72131,0 -1.74763,-5.14396 0,5.14396 -0.77077,0"
+           id="path3662"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+      <g
+         id="text2638"
+         style="font-size:8.25130367px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 239.84053,313.69965 0,-5.20945 -1.94598,0 0,-0.697 4.68164,0 0,0.697 -1.95404,0 0,5.20945 -0.78162,0"
+           id="path2883"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 243.39004,313.69965 0,-5.90645 1.17646,0 1.39805,4.18205 c 0.12892,0.38947 0.22293,0.6809 0.28202,0.87429 0.0671,-0.21488 0.1719,-0.53048 0.31426,-0.94681 l 1.41417,-4.10953 1.05155,0 0,5.90645 -0.75341,0 0,-4.94353 -1.71634,4.94353 -0.70506,0 -1.70828,-5.02814 0,5.02814 -0.75342,0"
+           id="path2885"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/img/login-background.jpg b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/img/login-background.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..49c7832642fe158585628b579f1b2f971aaf1f8b
Binary files /dev/null and b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/resources/img/login-background.jpg differ
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/theme.properties b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/theme.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ff5778df76922c344600c8644acefa9458e4a74e
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/theme.properties
@@ -0,0 +1,2 @@
+parent=keycloak
+styles=css/custom.css
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/webauthn-register.ftl b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/webauthn-register.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..92c21c0be5ad80cc01cadcfbc59d1ed62a7e6d4a
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/login/webauthn-register.ftl
@@ -0,0 +1,170 @@
+    <#import "template.ftl" as layout>
+    <@layout.registrationLayout; section>
+    <#if section = "title">
+        title
+    <#elseif section = "header">
+        <span class="${properties.kcWebAuthnKeyIcon}"></span>
+        ${kcSanitize(msg("webauthn-registration-title"))?no_esc}
+    <#elseif section = "form">
+        <div class="alert alert-warning">
+        <span class="${properties.kcFeedbackWarningIcon}"></span>
+        ${kcSanitize(msg("webauthn-registration-warning"))?no_esc}
+        </div>
+
+        <form id="register" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
+            <div class="${properties.kcFormGroupClass!}">
+                <input type="hidden" id="clientDataJSON" name="clientDataJSON"/>
+                <input type="hidden" id="attestationObject" name="attestationObject"/>
+                <input type="hidden" id="publicKeyCredentialId" name="publicKeyCredentialId"/>
+                <input type="hidden" id="authenticatorLabel" name="authenticatorLabel"/>
+                <input type="hidden" id="error" name="error"/>
+            </div>
+        </form>
+
+        <script type="text/javascript" src="${url.resourcesCommonPath}/node_modules/jquery/dist/jquery.min.js"></script>
+        <script type="text/javascript" src="${url.resourcesPath}/js/base64url.js"></script>
+        <script type="text/javascript">
+
+            function registerSecurityKey() {
+                // mandatory parameters
+                let challenge = "${challenge}";
+                let userid = "${userid}";
+                let username = "${username}";
+
+                let signatureAlgorithms = "${signatureAlgorithms}";
+                let pubKeyCredParams = getPubKeyCredParams(signatureAlgorithms);
+
+                let rpEntityName = "${rpEntityName}";
+                let rp = {name: rpEntityName};
+
+                let publicKey = {
+                    challenge: base64url.decode(challenge, {loose: true}),
+                    rp: rp,
+                    user: {
+                        id: base64url.decode(userid, {loose: true}),
+                        name: username,
+                        displayName: username
+                    },
+                    pubKeyCredParams: pubKeyCredParams,
+                };
+
+                // optional parameters
+                let rpId = "${rpId}";
+                publicKey.rp.id = rpId;
+
+                let attestationConveyancePreference = "${attestationConveyancePreference}";
+                if (attestationConveyancePreference !== 'not specified') publicKey.attestation = attestationConveyancePreference;
+
+                let authenticatorSelection = {};
+                let isAuthenticatorSelectionSpecified = false;
+
+                let authenticatorAttachment = "${authenticatorAttachment}";
+                if (authenticatorAttachment !== 'not specified') {
+                    authenticatorSelection.authenticatorAttachment = authenticatorAttachment;
+                    isAuthenticatorSelectionSpecified = true;
+                }
+
+                let requireResidentKey = "${requireResidentKey}";
+                if (requireResidentKey !== 'not specified') {
+                    if (requireResidentKey === 'Yes')
+                        authenticatorSelection.requireResidentKey = true;
+                    else
+                        authenticatorSelection.requireResidentKey = false;
+                    isAuthenticatorSelectionSpecified = true;
+                }
+
+                let userVerificationRequirement = "${userVerificationRequirement}";
+                if (userVerificationRequirement !== 'not specified') {
+                    authenticatorSelection.userVerification = userVerificationRequirement;
+                    isAuthenticatorSelectionSpecified = true;
+                }
+
+                if (isAuthenticatorSelectionSpecified) publicKey.authenticatorSelection = authenticatorSelection;
+
+                let createTimeout = ${createTimeout};
+                if (createTimeout != 0) publicKey.timeout = createTimeout * 1000;
+
+                let excludeCredentialIds = "${excludeCredentialIds}";
+                let excludeCredentials = getExcludeCredentials(excludeCredentialIds);
+                if (excludeCredentials.length > 0) publicKey.excludeCredentials = excludeCredentials;
+
+                navigator.credentials.create({publicKey})
+                    .then(function (result) {
+                        window.result = result;
+                        let clientDataJSON = result.response.clientDataJSON;
+                        let attestationObject = result.response.attestationObject;
+                        let publicKeyCredentialId = result.rawId;
+
+                        $("#clientDataJSON").val(base64url.encode(new Uint8Array(clientDataJSON), {pad: false}));
+                        $("#attestationObject").val(base64url.encode(new Uint8Array(attestationObject), {pad: false}));
+                        $("#publicKeyCredentialId").val(base64url.encode(new Uint8Array(publicKeyCredentialId), {pad: false}));
+
+                        let initLabel = "WebAuthn Authenticator (Default Label)";
+                        let labelResult = window.prompt("Please input your registered authenticator's label", initLabel);
+                        if (labelResult === null) labelResult = initLabel;
+                        $("#authenticatorLabel").val(labelResult);
+
+                        $("#register").submit();
+
+                    })
+                    .catch(function (err) {
+                        $("#error").val(err);
+                        $("#register").submit();
+
+                    });
+            }
+
+            function getPubKeyCredParams(signatureAlgorithms) {
+                let pubKeyCredParams = [];
+                if (signatureAlgorithms === "") {
+                    pubKeyCredParams.push({type: "public-key", alg: -7});
+                    return pubKeyCredParams;
+                }
+                let signatureAlgorithmsList = signatureAlgorithms.split(',');
+
+                for (let i = 0; i < signatureAlgorithmsList.length; i++) {
+                    pubKeyCredParams.push({
+                        type: "public-key",
+                        alg: signatureAlgorithmsList[i]
+                    });
+                }
+                return pubKeyCredParams;
+            }
+
+            function getExcludeCredentials(excludeCredentialIds) {
+                let excludeCredentials = [];
+                if (excludeCredentialIds === "") return excludeCredentials;
+
+                let excludeCredentialIdsList = excludeCredentialIds.split(',');
+
+                for (let i = 0; i < excludeCredentialIdsList.length; i++) {
+                    excludeCredentials.push({
+                        type: "public-key",
+                        id: base64url.decode(excludeCredentialIdsList[i],
+                        {loose: true})
+                    });
+                }
+                return excludeCredentials;
+            }
+        </script>
+
+        <#if !isSetRetry?has_content && isAppInitiatedAction?has_content>
+            <input type="submit"
+                   class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
+                   id="registerWebAuthnAIA" value="${msg("doRegister")}" onclick="registerSecurityKey()"
+            />
+            <form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-webauthn-settings-form"
+                  method="post">
+                <button type="submit"
+                        class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
+                        id="cancelWebAuthnAIA" name="cancel-aia" value="true"/>${msg("doCancel")}
+                </button>
+            </form>
+        <#else>
+            <script>
+                registerSecurityKey();
+            </script>
+        </#if>
+
+    </#if>
+    </@layout.registrationLayout>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/index.ftl b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/index.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..47436bd6d4faf1f9857c7673c4c4f52618c56fe7
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/index.ftl
@@ -0,0 +1,138 @@
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright (c) 2011, Red Hat, Inc., and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+ 
+<html>
+<head>
+    <title>Welcome to ${productNameFull}</title>
+
+    <meta charset="utf-8">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="robots" content="noindex, nofollow">
+
+    <link rel="shortcut icon" href="${resourcesCommonPath}/img/favicon.ico" />
+
+    <#if properties.stylesCommon?has_content>
+        <#list properties.stylesCommon?split(' ') as style>
+            <link href="${resourcesCommonPath}/${style}" rel="stylesheet" />
+        </#list>
+    </#if>
+    <#if properties.styles?has_content>
+        <#list properties.styles?split(' ') as style>
+            <link href="${resourcesPath}/${style}" rel="stylesheet" />
+        </#list>
+    </#if>
+</head>
+
+<body>
+<div class="container-fluid">
+  <div class="row">
+    <div class="col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2">
+      <div class="welcome-header">
+        <img src="${resourcesPath}/archlinux-logo-light.svg" alt="${productName}" border="0" />
+        <h1>Welcome to <strong>${productNameFull}</strong></h1>
+      </div>
+      <div class="row">
+        <div class="col-xs-12 col-sm-4">
+          <div class="card-pf h-l">
+            <#if successMessage?has_content>
+                <p class="alert success">${successMessage}</p>
+            <#elseif errorMessage?has_content>
+                <p class="alert error">${errorMessage}</p>
+                <h3><img src="welcome-content/user.png">Administration Console</h3>
+            <#elseif bootstrap>
+                <#if localUser>
+                    <h3><img src="welcome-content/user.png">Administration Console</h3>
+                    <p>Please create an initial admin user to get started.</p>
+                <#else>
+                    <p class="welcome-message">
+                        <img src="welcome-content/alert.png">You need local access to create the initial admin user. <br><br>Open <a href="http://localhost:8080/auth">http://localhost:8080/auth</a>
+                        <br>or use the add-user-keycloak script.
+                    </p>
+                </#if>
+            </#if>
+
+            <#if bootstrap && localUser>
+                <form method="post" class="welcome-form">
+                    <p>
+                        <label for="username">Username</label>
+                        <input id="username" name="username" />
+                    </p>
+
+                    <p>
+                        <label for="password">Password</label>
+                        <input id="password" name="password" type="password" />
+                    </p>
+
+                    <p>
+                        <label for="passwordConfirmation">Password confirmation</label>
+                        <input id="passwordConfirmation" name="passwordConfirmation" type="password" />
+                    </p>
+
+                    <input id="stateChecker" name="stateChecker" type="hidden" value="${stateChecker}" />
+
+                    <button id="create-button" type="submit" class="btn btn-primary">Create</button>
+                </form>
+            </#if>
+            <div class="welcome-primary-link">
+              <h3><a href="${adminUrl}"><img src="welcome-content/user.png">Administration Console <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
+              <div class="description">
+                Centrally manage all aspects of the ${productNameFull} server
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="col-xs-12 col-sm-4">
+          <div class="card-pf h-l">
+            <h3><a href="${properties.documentationUrl}"><img class="doc-img" src="welcome-content/admin-console.png">Wiki <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
+            <div class="description">
+
+              Your source for Arch Linux documentation on the web
+
+
+            </div>
+          </div>
+        </div>
+        <div class="col-xs-12 col-sm-4">
+        <#if properties.displayCommunityLinks = "true">
+          <div class="card-pf h-m">
+            <h3><a href="https://www.archlinux.org/"><img src="welcome-content/keycloak-project.png">Arch Linux Project <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
+          </div>
+          <div class="card-pf h-m">
+            <h3><a href="https://lists.archlinux.org/listinfo/arch-devops"><img src="welcome-content/mail.png">Mailing List <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
+          </div>
+          <div class="card-pf h-m">
+            <h3><a href="https://gitlab.archlinux.org/archlinux/infrastructure/-/issues"><img src="welcome-content/bug.png">Report an issue <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
+          </div>
+        </#if>
+        </div>
+      </div>
+      <div class='footer'>
+        <#if properties.displayFooter = "true">
+        <a href="http://www.jboss.org"><img src="welcome-content/jboss_community.png" alt="JBoss and JBoss Community"></a>
+        </#if>
+      </div>
+    </div>
+  </div>
+</div>
+</body>
+</html>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/archlinux-logo-light.svg b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/archlinux-logo-light.svg
new file mode 100644
index 0000000000000000000000000000000000000000..5fd0716fd855468528b2807136a434b94654c851
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/archlinux-logo-light.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.0"
+   width="600"
+   height="199.41692"
+   id="svg2424">
+  <defs
+     id="defs2426">
+    <linearGradient
+       x1="112.49854"
+       y1="6.1372099"
+       x2="112.49853"
+       y2="129.3468"
+       id="path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(287,-83)">
+      <stop
+         id="stop193"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop195"
+         style="stop-color:#ffffff;stop-opacity:0.27450982"
+         offset="1" />
+      <midPointStop
+         offset="0"
+         style="stop-color:#FFFFFF"
+         id="midPointStop197" />
+      <midPointStop
+         offset="0.5"
+         style="stop-color:#FFFFFF"
+         id="midPointStop199" />
+      <midPointStop
+         offset="1"
+         style="stop-color:#000000"
+         id="midPointStop201" />
+    </linearGradient>
+    <linearGradient
+       x1="541.33502"
+       y1="104.50665"
+       x2="606.91248"
+       y2="303.14029"
+       id="linearGradient2544"
+       xlink:href="#path1082_2_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.3937741,0,0,0.393752,357.51969,122.00151)" />
+    <linearGradient
+       id="linearGradient3388">
+      <stop
+         id="stop3390"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop3392"
+         style="stop-color:#000000;stop-opacity:0.37113401"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="490.72305"
+       y1="237.72447"
+       x2="490.72305"
+       y2="183.9644"
+       id="linearGradient4416"
+       xlink:href="#linearGradient3388"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.749107,0,0,0.749107,-35.459862,91.44108)" />
+  </defs>
+  <g
+     transform="translate(-34.777313,-129.80241)"
+     id="layer1">
+    <g
+       transform="matrix(0.8746356,0,0,0.8746356,14.730518,23.408954)"
+       id="g2424">
+      <g
+         transform="matrix(0.6378586,0,0,0.6378586,36.486487,2.17139)"
+         id="g2809"
+         style="fill:#ffffff;fill-opacity:1">
+        <path
+           d="m 339.96875,309.09375 c -14.47141,-0.0239 -26.4812,2.94367 -31.125,4.5625 l -4.78125,25.8125 c -0.0116,0.0951 23.79543,-6.34855 34.28125,-5.96875 17.36158,0.62381 18.95948,6.63541 18.65625,14.75 0.29595,0.47462 -4.47933,-7.33192 -19.5,-7.59375 -18.94961,-0.32687 -45.69284,6.70947 -45.65625,35.3125 -0.51086,32.17412 24.03361,41.63882 40.75,41.8125 15.02821,-0.27364 22.0777,-5.69136 25.9375,-8.59375 5.07124,-5.30236 10.87308,-10.63447 16.40625,-17.03125 -5.23567,9.51278 -9.77472,16.0898 -14.5,21.125 l 0,4.25 22.84375,-3.84375 0.15625,-62.09375 c -0.23141,-8.78839 5.04123,-42.41827 -43.46875,-42.5 z m -3.28125,54.0625 c 9.46889,0.12995 20.32788,4.79708 20.34375,16.03125 0.049,10.21821 -12.80005,15.71183 -21.15625,15.625 -8.35976,-0.0868 -19.45093,-6.56982 -19.5,-16.53125 0.16016,-8.90444 10.45953,-15.35418 20.3125,-15.125 z"
+           id="path2284"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 398.50106,314.83145 -0.15505,102.82693 26.61213,-5.12724 0.0449,-58.30157 c 0.006,-8.68089 12.40554,-18.82451 27.9627,-18.66287 3.30202,-5.97408 9.5087,-21.24219 11.02088,-24.71514 -34.75649,-0.0833 -35.19897,9.98993 -41.24398,14.94517 -0.0631,-9.45285 -0.0213,-15.12741 -0.0213,-15.12741 l -24.2202,4.16213 z"
+           id="path2286"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 548.2688,328.33058 c -0.25696,-0.12068 -13.87938,-15.93419 -41.26638,-16.0589 -25.65249,-0.42638 -54.42578,9.51895 -54.88631,52.5328 0.22457,37.81852 27.6402,52.59809 55.0314,52.88627 29.31292,0.30451 40.97654,-18.32947 41.67615,-18.79124 -3.49762,-3.0321 -16.59792,-16.0131 -16.59792,-16.0131 0,0 -8.18236,11.65102 -24.05802,11.79913 -15.87942,0.1512 -29.68245,-12.27325 -29.87805,-29.60905 -0.20349,-17.33595 12.68881,-26.72821 29.99725,-27.48687 14.98466,-0.003 23.6297,9.67334 23.6297,9.67334 l 16.35218,-18.93238 z"
+           id="path2288"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 581.8125,278.84375 -25.125,5.90625 0.1875,133.9375 24.75,-4.46875 0.28125,-63.03125 c 0.0529,-6.60927 9.56127,-16.75916 25.4375,-16.4375 15.17973,0.15775 18.57236,10.11767 18.53125,11.375 l 0.4375,72.96875 24.40625,-4.3125 0.0937,-77.375 c 0.1607,-7.44539 -16.30833,-23.16954 -42.78125,-23.28125 -12.58087,0.0202 -19.54815,2.86825 -23.09375,4.96875 -6.06656,4.68565 -12.9998,9.17543 -19.8125,14.90625 6.29809,-8.09099 11.58551,-13.68516 16.75,-17.84375 l -0.0625,-37.3125 z"
+           id="path2290"
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <g
+         transform="matrix(0.9443373,0,0.01336345,0.9443373,78.345657,-412.48879)"
+         id="g5326"
+         style="fill:#1793d1;fill-opacity:1;stroke:none">
+        <path
+           d="m 400.67581,629.79609 7.68167,-1.91575 -0.92851,91.20792 -7.79574,1.32426 1.04258,-90.61643 z"
+           id="path2292"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 421.10266,657.01757 6.75064,-2.9867 -0.86808,65.39931 -6.49779,1.33915 0.61523,-63.75176 z m -1.26059,-23.58316 5.47167,-4.41533 4.42261,4.99952 -5.47558,4.53221 -4.4187,-5.1164 z"
+           id="path2294"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 440.44273,655.82614 7.67755,-1.56201 -0.1573,13.6722 c -0.007,0.58717 4.4194,-15.27364 24.68502,-14.92094 19.67986,0.10952 22.68401,15.34634 22.5291,18.76237 l -0.43759,48.0783 -6.73044,1.45631 0.63316,-47.489 c 0.0974,-1.38684 -2.88144,-13.11441 -16.78906,-13.15754 -13.90509,-0.0404 -23.68364,10.10048 -23.75821,16.57937 l -0.48127,41.83477 -7.80388,2.0313 0.63292,-65.28513 z"
+           id="path2296"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 561.53301,720.20203 -7.6776,1.56186 0.15737,-13.67198 c 0.007,-0.58742 -4.42201,15.27361 -24.68504,14.92086 -19.67983,-0.10944 -22.68399,-15.34626 -22.52908,-18.76229 l 0.43757,-48.07861 8.15674,-1.64226 -0.54644,47.48988 c -0.0149,1.29682 1.36845,13.29979 15.27604,13.3426 13.90511,0.0405 23.76622,-8.37359 24.01453,-21.04416 l 0.43105,-37.46902 7.5978,-1.93195 -0.63294,65.28507 z"
+           id="path2298"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+        <path
+           d="m 577.45461,655.28678 -5.42715,4.20017 20.19894,26.93328 -22.39092,31.11622 5.63499,4.226 21.04365,-28.8967 20.8779,29.58159 5.32727,-4.20103 -22.37578,-31.62866 18.56963,-25.5775 -5.53193,-4.73429 -16.92109,23.66778 -19.00551,-24.68686 z"
+           id="path2300"
+           style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      </g>
+      <path
+         d="m 105.8125,16.625 c -7.39687,18.135158 -11.858304,29.997682 -20.09375,47.59375 5.04936,5.35232 11.247211,11.585364 21.3125,18.625 C 96.210077,78.390904 88.828713,73.920352 83.3125,69.28125 72.7727,91.274163 56.259864,122.60209 22.75,182.8125 49.087628,167.60733 69.504089,158.23318 88.53125,154.65625 87.714216,151.1422 87.2497,147.34107 87.28125,143.375 l 0.03125,-0.84375 c 0.417917,-16.87382 9.195665,-29.84979 19.59375,-28.96875 10.39809,0.88104 18.48041,15.28242 18.0625,32.15625 -0.0786,3.17512 -0.43674,6.22955 -1.0625,9.0625 18.82058,3.68164 39.01873,13.03179 65,28.03125 -5.123,-9.4318 -9.69572,-17.93388 -14.0625,-26.03125 -6.87839,-5.33121 -14.05289,-12.2698 -28.6875,-19.78125 10.05899,2.61375 17.2611,5.62932 22.875,9 C 124.63297,63.338161 121.03766,52.354109 105.8125,16.625 z"
+         transform="matrix(1.1433333,0,0,1.1433333,22.920168,121.64318)"
+         id="path2518"
+         style="fill:#1793d1;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+      <g
+         id="text2634"
+         style="font-size:8.44138241px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 685.46692,263.83624 0,-5.32944 -1.99082,0 0,-0.71307 4.7895,0 0,0.71307 -1.99906,0 0,5.32944 -0.79962,0"
+           id="path3660"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 689.0982,263.83624 0,-6.04251 1.20355,0 1.43026,4.2784 c 0.13189,0.39843 0.22806,0.69658 0.28852,0.89442 0.0687,-0.21983 0.17586,-0.5427 0.3215,-0.96862 l 1.44674,-4.2042 1.07578,0 0,6.04251 -0.77077,0 0,-5.05741 -1.75587,5.05741 -0.72131,0 -1.74763,-5.14396 0,5.14396 -0.77077,0"
+           id="path3662"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+      <g
+         id="text2638"
+         style="font-size:8.25130367px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono">
+        <path
+           d="m 239.84053,313.69965 0,-5.20945 -1.94598,0 0,-0.697 4.68164,0 0,0.697 -1.95404,0 0,5.20945 -0.78162,0"
+           id="path2883"
+           style="fill:#ffffff;fill-opacity:1" />
+        <path
+           d="m 243.39004,313.69965 0,-5.90645 1.17646,0 1.39805,4.18205 c 0.12892,0.38947 0.22293,0.6809 0.28202,0.87429 0.0671,-0.21488 0.1719,-0.53048 0.31426,-0.94681 l 1.41417,-4.10953 1.05155,0 0,5.90645 -0.75341,0 0,-4.94353 -1.71634,4.94353 -0.70506,0 -1.70828,-5.02814 0,5.02814 -0.75342,0"
+           id="path2885"
+           style="fill:#ffffff;fill-opacity:1" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/css/custom.css b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/css/custom.css
new file mode 100644
index 0000000000000000000000000000000000000000..82967706efa40d4e2724acc592e67c344cbb3a9d
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/css/custom.css
@@ -0,0 +1,14 @@
+@import 'welcome.css';
+
+body {
+    background: #fff url('../welcome-background.jpg') no-repeat center bottom fixed;
+}
+
+.welcome-header {
+	color: white;
+}
+
+.welcome-header img {
+	width: 200px;
+	margin-bottom: 10px;
+}
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/welcome-background.jpg b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/welcome-background.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..49c7832642fe158585628b579f1b2f971aaf1f8b
Binary files /dev/null and b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/resources/welcome-background.jpg differ
diff --git a/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/theme.properties b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/theme.properties
new file mode 100644
index 0000000000000000000000000000000000000000..a2aedb582a9ce3aafc1134370e864dacd462df43
--- /dev/null
+++ b/roles/keycloak/files/providers/keycloak-mailpass-rest/docker/archlinux/welcome/theme.properties
@@ -0,0 +1,5 @@
+parent=keycloak
+documentationUrl=https://wiki.archlinux.org
+displayCommunityLinks=true
+displayFooter=false
+styles=css/custom.css