initial version

This commit is contained in:
Rick van Lieshout 2022-08-25 22:06:45 +02:00
commit 400f46997b
42 changed files with 2222 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
data
test

9
CHANGELOG.md Normal file
View File

@ -0,0 +1,9 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.0]
Initial version of theme with logo etc

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# Keycloak customization
Repo to hold Keycloak customizations for [https://sso.mastermindzh.tech](https://sso.mastermindzh.tech)
## Getting started
- `docker-compose up`
- [http://localhost:10000](http://localhost:10000)
- admin/admin
- done? 😄
## deployment
We could use the helm chart or just use the same container from docker-compose.yml.
Either way, make sure to pass the custom welcome theme to the start command:
`- KEYCLOAK_EXTRA_ARGS="--spi-theme-welcome-theme=mastermindzh.tech"`

5
TODO.md Normal file
View File

@ -0,0 +1,5 @@
- see if I can re-use a single set of logos/favicons... etc
- new background image
- new login theme
- increase text size in logo
- increase size of favicon? (remove "hair")?

27
docker-compose.yml Normal file
View File

@ -0,0 +1,27 @@
version: "2"
services:
postgresql:
image: docker.io/bitnami/postgresql:11
environment:
- ALLOW_EMPTY_PASSWORD=yes
- POSTGRESQL_USERNAME=bn_keycloak
- POSTGRESQL_DATABASE=bitnami_keycloak
volumes:
# - "postgresql_data:/bitnami/postgresql"
- "./data:/bitnami/postgresql"
keycloak:
image: docker.io/bitnami/keycloak:18
volumes:
- ./themes:/opt/bitnami/keycloak/themes
depends_on:
- postgresql
environment:
- KEYCLOAK_ADMIN_USER=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
- KEYCLOAK_EXTRA_ARGS="--spi-theme-welcome-theme=mastermindzh.tech"
ports:
- "10000:8080"
volumes:
postgresql_data:
driver: local

22
package.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "sso.mastermindzh.tech",
"version": "1.0.0",
"description": "Theme for keycloak SSO",
"keywords": [
"Keycloak",
"mastermindzh.tech"
],
"author": "Rick van Lieshout",
"homepage": "https://rickvanlieshout.com",
"license": "MIT",
"private": false,
"engines": {
"node": ">=10.9.0",
"npm": ">=6.0.0"
},
"dependencies": {},
"devDependencies": {},
"scripts": {
"start": "docker-compose up -d"
}
}

View File

@ -0,0 +1,293 @@
<!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/logo.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}'.replace('&amp;', '&');
</#if>
<#if msg??>
var locale = '${locale}';
<#outputformat "JavaScript">
var l18nMsg = JSON.parse('${msgJSON?js_string}');
</#outputformat>
<#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/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 rel="stylesheet" type="text/css" href="${resourceCommonUrl}/web_modules/@patternfly/patternfly/patternfly-addons.css"/>
<link href="${resourceUrl}/public/layout.css" rel="stylesheet"/>
</head>
<body>
<script>
var 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.loadingLogo?has_content>
<img src="${resourceUrl}${properties.loadingLogo}" alt="Logo" class="brand">
<#else>
<img src="${resourceUrl}/public/logo.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>
</svg>
</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/logo.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 pf-u-display-none pf-u-display-flex-on-md">
<a id="landingReferrerLink" href="${referrer_uri}" class="pf-c-button pf-m-link" tabindex="0">
<span class="pf-c-button__icon pf-m-start">
<i class="pf-icon pf-icon-arrow" aria-hidden="true"></i>
</span>
${msg("backToAdminConsole")}
</a>
</div>
</#if>
<div class="pf-c-page__header-tools-group pf-m-icons pf-u-display-none pf-u-display-flex-on-md pf-u-mr-md">
<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 pf-u-display-none-on-md">
<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("backToAdminConsole")}</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-limit-width pf-m-light pf-m-shadow-bottom">
<div class="pf-c-page__main-body">
<div class="pf-c-content" id="landingWelcomeMessage">
<h1>${msg("accountManagementWelcomeMessage")}</h1>
</div>
</div>
</section>
<section class="pf-c-page__main-section pf-m-limit-width pf-m-overflow-scroll">
<div class="pf-c-page__main-body">
<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" id="landing-${item.id}">
<div class="pf-c-card pf-m-full-height">
<div>
<div class="pf-c-card__title pf-c-content">
<h2 class="pf-u-display-flex pf-u-w-100 pf-u-flex-direction-column">
<#if item.icon??>
<i class="pf-icon ${item.icon}"></i>
<#elseif item.iconSvg??>
<img src="${item.iconSvg}" alt="icon"/>
</#if>
${msg(item.label)}
</h2>
</div>
<div class="pf-c-card__body">
<#if item.descriptionLabel??>
<p class="pf-u-mb-md">${msg(item.descriptionLabel)}</p>
</#if>
<#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>
</div>
</#list>
</div>
</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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,126 @@
/* Globals */
.brand {
height: 35px;
}
.delete-button {
width: 150px;
height: 50px;
}
@media (max-width: 320px) {
.delete-button {
width: 120px;
height: 50px;
}
}
/* Linked Accounts screen */
.idp-icon-social {
width: 32px;
height: 32px;
}
#github-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_github_transparent.svg);
}
#linkedin-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_linkedin_transparent.svg);
}
#facebook-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_facebook_transparent.svg);
}
#google-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_google_transparent.svg);
}
#microsoft-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_microsoft_transparent.svg);
}
#instagram-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_instagram_transparent.svg);
}
#stackoverflow-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_stack_transparent.svg);
}
#twitter-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_twitter_transparent.svg);
}
#openshift-idp-icon-social {
background-image: url(../img/socialmedia/socialmedia_icons_openshift_transparent.svg);
}
/* Account Page screen */
.personal-info-form .pf-c-form__group-control {
max-width: 600px;
}
/* Device Activity screen */
.signed-in-device-list .pf-c-data-list__item-row {
--pf-c-data-list__item-row--PaddingRight: 0;
--pf-c-data-list__item-row--PaddingLeft: 0;
}
.signed-in-device-list .pf-c-data-list__expandable-content-body {
--pf-c-data-list__expandable-content-body--PaddingRight: 0;
}
.signed-in-device-grid {
grid-template-columns: auto repeat(11, [col-start] 1fr);
}
.signed-in-device-list.pf-c-data-list {
--pf-c-data-list--sm--BorderTopWidth: 0;
}
.pf-c-data-list__item {
--pf-c-data-list__item--BorderBottomWidth: 1px;
--pf-c-data-list__item--BorderBottomColor: var(--pf-global--BorderColor--100);
}
.signed-in-device-list.pf-c-data-list {
--pf-c-data-list--BorderTopWidth: 0;
}
@media (min-width: 576px) {
.pf-c-data-list__item {
position: relative;
display: flex;
flex-direction: column;
background-color: var(--pf-c-data-list__item--BackgroundColor);
border-bottom: var(--pf-c-data-list__item--BorderBottomWidth) solid var(--pf-c-data-list__item--BorderBottomColor);
}
.signed-in-device-list.pf-c-data-list {
--pf-c-data-list--BorderTopWidth: 0;
}
}
@media (min-width: 768px) {
.signed-in-device-list .pf-c-description-list {
--pf-c-description-list--GridTemplateColumns--count: 5;
}
}
/* Signing in screen */
.title-case:first-letter,
.cred-title:first-letter,
#otp-not-set-up .pf-c-empty-state__body:first-letter {
text-transform: capitalize
}
/* Applications screen */
#applications-list-header .pf-c-data-list__item-content {
--pf-c-data-list__item-content--md--PaddingBottom: 1rem;
}
.pf-u-pl-35xl {
padding-left: 4.5rem;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,19 @@
parent=keycloak.v2
deprecatedMode=false
scripts=welcome-page-scripts.js
developmentMode=false
# This is the logo in upper lefthand corner.
# It must be a relative path.
logo=/public/logo.png
loadingLogo=/public/loadingLogo.png
# This is the link followed when clicking on the logo.
# It can be any valid URL, including an external site.
logoUrl=./
# This is the icon for the account console.
# It must be a relative path.
favIcon=/public/favicon.ico

View File

@ -0,0 +1,496 @@
html,
body {
height: 100%;
}
form {
margin-top: 20px;
}
table {
margin-top: 20px;
}
.required {
color: #f00;
}
.tooltip-inner {
min-width: 200px;
}
.margin-top {
margin-top: 20px;
}
.no-margin-top {
margin-top: 0px !important;
}
table {
max-width: 100%;
}
td.clip {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 0;
}
th.w-10 {
width: 10%;
}
th.w-15 {
width: 15%;
}
th.w-20 {
width: 20%;
}
th.w-25 {
width: 25%;
}
th.w-30 {
width: 30%;
}
th.w-35 {
width: 35%;
}
th.w-40 {
width: 40%;
}
/*********** Loading ***********/
.loading {
background-color: #f5f5f5;
border: 1px solid #eee;
position: absolute;
bottom: 0px;
left: 0px;
padding: 2px 200px 2px 5px;
}
/*********** Feedback ***********/
.feedback-aligner {
position: fixed;
top: 15px;
text-align: center;
width: 100%;
height: 0;
z-index: 100;
}
.feedback-aligner .alert {
border-radius: 2px;
border-width: 1px;
display: inline-block;
position: relative;
}
/*********** On-Off Switch ***********/
.onoffswitch {
-moz-user-select: none;
height: 26px;
position: relative;
width: 62px;
}
.onoffswitch .onoffswitch-checkbox {
display: none;
}
.onoffswitch .onoffswitch-label {
border: 1px solid #bbb;
border-radius: 2px;
cursor: pointer;
display: block;
overflow: hidden;
width: 62px;
}
.onoffswitch .onoffswitch-inner {
display: block;
margin-left: -100%;
transition: margin 0.3s ease-in 0s;
width: 200%;
}
.onoffswitch .onoffswitch-inner > span {
-moz-box-sizing: border-box;
color: white;
float: left;
font-size: 11px;
font-family: "Open Sans", sans-serif;
font-weight: bold;
height: 24px;
line-height: 24px;
padding: 0;
width: 50%;
}
.onoffswitch .onoffswitch-switch {
background-image: linear-gradient(top, #fafafa 0%, #ededed 100%);
background-image: -o-linear-gradient(top, #fafafa 0%, #ededed 100%);
background-image: -moz-linear-gradient(top, #fafafa 0%, #ededed 100%);
background-image: -webkit-linear-gradient(top, #fafafa 0%, #ededed 100%);
background-image: -ms-linear-gradient(top, #fafafa 0%, #ededed 100%);
background-image: -webkit-gradient(
linear,
left top,
left bottom,
color-stop(0, #fafafa),
color-stop(1, 0, #ededed)
);
border: 1px solid #aaa;
border-radius: 2px;
bottom: 0;
margin: 0;
position: absolute;
right: 39px;
top: 0;
transition: all 0.3s ease-in 0s;
-webkit-transition: all 0.3s ease-in 0s;
width: 23px;
}
.onoffswitch .onoffswitch-inner .onoffswitch-active {
background-image: linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -o-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -moz-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -ms-linear-gradient(top, #00a9ec 0%, #009bd3 100%);
background-image: -webkit-gradient(
linear,
left top,
left bottom,
color-stop(0, #00a9ec),
color-stop(1, 0, #009bd3)
);
color: #ffffff;
padding-left: 10px;
}
.onoffswitch-checkbox:disabled
+ .onoffswitch-label
.onoffswitch-inner
.onoffswitch-active,
.onoffswitch-checkbox:disabled
+ .onoffswitch-label
.onoffswitch-inner
.onoffswitch-inactive {
background-image: none;
background-color: #e5e5e5;
color: #9d9fa1;
}
.onoffswitch .onoffswitch-inner .onoffswitch-inactive {
background: linear-gradient(#fefefe, #e8e8e8) repeat scroll 0 0 transparent;
color: #4d5258;
padding-right: 10px;
text-align: right;
}
.onoffswitch
.onoffswitch-checkbox:checked
+ .onoffswitch-label
.onoffswitch-inner {
margin-left: 0;
}
.onoffswitch
.onoffswitch-checkbox:checked
+ .onoffswitch-label
.onoffswitch-switch {
right: 0;
}
/*********** Select 2 ***********/
.select2-container {
width: 100%;
}
.select2-container-multi .select2-choices .select2-search-field {
height: 26px;
}
/*********** html select ********/
.overflow-select {
overflow: auto;
}
/*********** New Menu ***********/
.sidebar-pf-left {
background: #292e34;
}
.sidebar-pf .nav-pills > li a i,
.sidebar-pf .nav-pills > li a span {
color: #72767b;
display: inline-block;
margin-right: 10px;
}
.sidebar-pf .nav-pills > li > a {
color: #dbdada;
padding: 0px 20px 0 30px !important;
line-height: 30px;
border-left-width: 12px;
border-left-style: solid;
border-left-color: #292e34;
margin-left: -6px;
}
.sidebar-pf .nav-pills > li > a:hover {
background: #393f44;
border-color: #292e34;
border-left-color: #393f44;
color: #fff;
}
.sidebar-pf .nav-pills > li > a:after {
display: none !important;
}
.sidebar-pf .nav-pills > li.active > a {
color: #fff;
background: #393f44 !important;
border-bottom: 1px solid #000 !important;
border-top: 1px solid #000 !important;
border-left-color: #39a5dc !important;
}
.sidebar-pf .nav-pills > li.active a i,
.sidebar-pf .nav-pills > li.active a span {
color: #39a5dc;
}
/*********** Realm selector ***********/
.realm-selector {
color: #fff;
margin: 0 -20px;
position: relative;
}
.realm-dropmenu {
display: none;
cursor: pointer;
position: absolute;
top: 60px;
left: 0;
right: 0;
z-index: 999;
background: #fff;
}
.realm-selector:hover .realm-dropmenu {
display: block;
}
.realm-add {
padding: 10px;
}
.realm-selector h2 {
font-size: 16px;
line-height: 60px;
padding: 0 20px;
margin: 0;
border-bottom: 1px solid #d5d5d6;
}
.realm-selector h2 i {
display: inline-block;
float: right;
line-height: 60px;
}
.realm-selector ul {
padding-left: 0;
margin: 0;
list-style: none;
max-height: 200px;
overflow-y: auto;
}
.realm-selector ul li a {
line-height: 60px;
padding: 0 20px;
border-bottom: 1px solid #d5d5d6;
line-height: 39px;
display: block;
font-size: 14px;
}
/*********** Overwrites header defaults ***********/
.navbar-pf {
border-top: none !important;
}
.navbar-pf .navbar-brand {
padding: 0;
height: 56px;
line-height: 56px;
background-position: center center;
background-image: url("../img/keycloak-logo.png");
background-size: contain;
background-repeat: no-repeat;
width: 90px;
}
.navbar-pf .navbar-utility .dropdown-toggle {
padding: 23px !important;
}
.clickable {
cursor: pointer;
}
h1 i {
color: #999999;
font-size: 18px;
margin-left: 10px;
}
/* Action cell */
.kc-action-cell {
background-color: #eeeeee;
background-image: linear-gradient(to bottom, #fafafa 0%, #ededed 100%);
background-repeat: repeat-x;
text-align: center;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
.kc-action-cell:hover {
background-color: #eeeeee;
background-image: none;
}
.kc-sorter span {
margin-left: 10px;
}
/* Time selector */
.time-selector input {
display: inline-block;
width: 120px;
padding-right: 0;
margin-right: 0;
}
.time-selector select {
display: inline-block;
width: 80px;
margin-left: 0;
padding-left: 0;
}
.ace_editor {
height: 600px;
width: 100%;
}
.kc-button-input-file input {
float: left;
width: 73%;
}
.kc-button-input-file label {
float: left;
margin-left: 2%;
width: 25%;
}
table.kc-authz-table-expanded {
margin-top: 0px !important;
}
.no-gutter > [class*="col-"] {
padding-right: 0 !important;
padding-left: 0 !important;
}
.password-conceal {
font-family: "text-security-disc";
font-size: 14px;
}
/* Deactivation styles for user-group membership tree models */
div[tree-model] li .deactivate {
color: #4a5053;
opacity: 0.4;
}
div[tree-model] li .deactivate_selected {
background-color: #dcdcdc;
font-weight: bold;
padding: 1px 5px;
}
/* search highlighting */
div[tree-model] li .highlight {
background-color: #aaddff;
}
/* Manage credentials */
table.credentials-table {
margin-top: 0;
margin-bottom: 20px;
}
table.credentials-table td {
vertical-align: middle !important;
}
table.credentials-table input[type="text"] {
width: 100%;
}
td.credential-arrows-cell {
width: 75px;
}
td.credential-label-cell {
padding: 5px !important;
}
td.credential-action-cell {
padding: 0px !important;
}
td.credential-action-cell div.kc-action-cell {
width: 100%;
height: 36px;
line-height: 34px;
}
td.credential-action-cell.expanded div.kc-action-cell {
border-bottom: 1px solid #d1d1d1;
}
table.credential-data-table td {
word-break: break-all;
}
table.credential-data-table tr:first-child td {
border-top: 0;
}
table.credential-data-table td:first-child {
width: 150px;
}
table.credential-data-table td.key {
text-align: right;
font-weight: bold;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,5 @@
parent=base
import=common/keycloak
styles=css/styles.css
stylesCommon=node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css node_modules/select2/select2.css lib/angular/treeview/css/angular.treeview.css node_modules/text-security/text-security.css

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1 @@
parent=base

View File

@ -0,0 +1,739 @@
.login-pf body {
background-size: cover;
height: 100%;
background: #fff url(../img/bg.jpg) no-repeat center bottom fixed;
background-size: cover;
}
/*IE compatibility*/
.pf-c-form-control {
font-size: 14px;
font-size: var(--pf-global--FontSize--sm);
border-width: 1px;
border-width: var(--pf-global--BorderWidth--sm);
border-color: #ededed #ededed #8a8d90 #ededed;
border-color: var(--pf-global--BorderColor--300)
var(--pf-global--BorderColor--300) var(--pf-global--BorderColor--200)
var(--pf-global--BorderColor--300);
background-color: #ffffff;
background-color: var(--pf-global--BackgroundColor--100);
height: 36px;
height: calc(
var(--pf-c-form-control--FontSize) * var(--pf-c-form-control--LineHeight) +
var(--pf-c-form-control--BorderWidth) * 2 +
var(--pf-c-form-control--PaddingTop) +
var(--pf-c-form-control--PaddingBottom)
);
padding: 5px 0.5rem;
padding: var(--pf-c-form-control--PaddingTop)
var(--pf-c-form-control--PaddingRight)
var(--pf-c-form-control--PaddingBottom)
var(--pf-c-form-control--PaddingLeft);
}
.pf-c-form-control:hover,
.pf-c-form-control:focus {
border-bottom-color: #0066cc;
border-bottom-color: var(--pf-global--primary-color--100);
border-bottom-width: 2px;
border-bottom-width: var(--pf-global--BorderWidth--md);
}
.pf-c-form-control[aria-invalid="true"] {
border-bottom-color: #c9190b;
border-bottom-color: var(--pf-global--danger-color--100);
border-bottom-width: 2px;
border-bottom-width: var(--pf-global--BorderWidth--md);
}
.pf-c-form-control {
border-color: rgb(128, 128, 128);
border-width: 3px;
border-radius: 4px;
}
.pf-c-alert.pf-m-inline {
margin-bottom: 0.5rem; /* default - IE compatibility */
margin-bottom: var(--pf-global--spacer--sm);
padding: 0.25rem;
padding: var(--pf-global--spacer--xs);
border: solid #ededed;
border: solid var(--pf-global--BorderColor--300);
border-width: 1px;
border-width: var(--pf-c-alert--m-inline--BorderTopWidth)
var(--pf-c-alert--m-inline--BorderRightWidth)
var(--pf-c-alert--m-inline--BorderBottomWidth)
var(--pf-c-alert--m-inline--BorderLeftWidth);
display: -ms-flexbox;
display: grid;
-ms-grid-columns: max-content 1fr max-content;
grid-template-columns: max-content 1fr max-content;
grid-template-columns: var(--pf-c-alert--grid-template-columns);
grid-template-rows: 1fr auto;
grid-template-rows: var(--pf-c-alert--grid-template-rows);
}
.pf-c-alert.pf-m-inline::before {
position: absolute;
top: -1px;
top: var(--pf-c-alert--m-inline--before--Top);
bottom: -1px;
bottom: var(--pf-c-alert--m-inline--before--Bottom);
left: 0;
width: 3px;
width: var(--pf-c-alert--m-inline--before--Width);
content: "";
background-color: #ffffff;
background-color: var(--pf-global--BackgroundColor--100);
}
.pf-c-alert.pf-m-inline.pf-m-success::before {
background-color: #92d400;
background-color: var(--pf-global--success-color--100);
}
.pf-c-alert.pf-m-inline.pf-m-danger::before {
background-color: #c9190b;
background-color: var(--pf-global--danger-color--100);
}
.pf-c-alert.pf-m-inline.pf-m-warning::before {
background-color: #f0ab00;
background-color: var(--pf-global--warning-color--100);
}
.pf-c-alert.pf-m-inline .pf-c-alert__icon {
padding: 1rem 0.5rem 1rem 1rem;
padding: var(--pf-c-alert--m-inline__icon--PaddingTop)
var(--pf-c-alert--m-inline__icon--PaddingRight)
var(--pf-c-alert--m-inline__icon--PaddingBottom)
var(--pf-c-alert--m-inline__icon--PaddingLeft);
font-size: 16px;
font-size: var(--pf-c-alert--m-inline__icon--FontSize);
}
.pf-c-alert.pf-m-success .pf-c-alert__icon {
color: #92d400;
color: var(--pf-global--success-color--100);
}
.pf-c-alert.pf-m-success .pf-c-alert__title {
color: #486b00;
color: var(--pf-global--success-color--200);
}
.pf-c-alert.pf-m-danger .pf-c-alert__icon {
color: #c9190b;
color: var(--pf-global--danger-color--100);
}
.pf-c-alert.pf-m-danger .pf-c-alert__title {
color: #a30000;
color: var(--pf-global--danger-color--200);
}
.pf-c-alert.pf-m-warning .pf-c-alert__icon {
color: #f0ab00;
color: var(--pf-global--warning-color--100);
}
.pf-c-alert.pf-m-warning .pf-c-alert__title {
color: #795600;
color: var(--pf-global--warning-color--200);
}
.pf-c-alert__title {
font-size: 14px; /* default - IE compatibility */
font-size: var(--pf-global--FontSize--sm);
padding: 5px 8px;
padding: var(--pf-c-alert__title--PaddingTop)
var(--pf-c-alert__title--PaddingRight)
var(--pf-c-alert__title--PaddingBottom)
var(--pf-c-alert__title--PaddingLeft);
}
.pf-c-button {
padding: 0.375rem 1rem;
padding: var(--pf-global--spacer--form-element) var(--pf-global--spacer--md);
border-radius: 4px;
box-shadow: 0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%),
0 1px 5px 0 rgb(0 0 0 / 12%);
}
/* default - IE compatibility */
.pf-m-primary {
color: #ffffff;
background-color: #0066cc;
background-color: var(--pf-global--primary-color--100);
}
/* default - IE compatibility */
.pf-m-primary:hover {
background-color: #004080;
background-color: var(--pf-global--primary-color--200);
}
/* default - IE compatibility */
.pf-c-button.pf-m-control {
border: solid 1px;
border: solid var(--pf-global--BorderWidth--sm);
border-color: rgba(230, 230, 230, 0.5);
}
/*End of IE compatibility*/
#kc-locale ul {
display: none;
position: absolute;
background-color: #fff;
list-style: none;
right: 0;
top: 20px;
min-width: 100px;
padding: 2px 0;
border: solid 1px #bbb;
}
#kc-locale:hover ul {
display: block;
margin: 0;
}
#kc-locale ul li a {
display: block;
padding: 5px 14px;
color: #000 !important;
text-decoration: none;
line-height: 20px;
}
#kc-locale ul li a:hover {
color: #4d5258;
background-color: #d4edfa;
}
#kc-locale-dropdown a {
color: #4d5258;
background: 0 0;
padding: 0 15px 0 0;
font-weight: 300;
}
#kc-locale-dropdown a:hover {
text-decoration: none;
}
a#kc-current-locale-link {
display: block;
padding: 0 5px;
}
/* a#kc-current-locale-link:hover {
background-color: rgba(0,0,0,0.2);
} */
a#kc-current-locale-link::after {
content: "\2c5";
margin-left: 4px;
}
.login-pf .container {
padding-top: 40px;
}
.login-pf a:hover {
color: #0099d3;
}
#kc-logo {
width: 100%;
}
#kc-logo-wrapper {
background-image: url(../img/keycloak-logo-2.png);
background-repeat: no-repeat;
height: 63px;
width: 300px;
margin: 62px auto 0;
}
div.kc-logo-text {
background-image: url(../img/logo-white.png);
background-repeat: no-repeat;
background-size: contain;
background-position: center;
height: 177px;
width: 680px;
margin: 0 auto;
}
div.kc-logo-text span {
display: none;
}
#kc-header {
color: #ededed;
overflow: visible;
white-space: nowrap;
}
#kc-header-wrapper {
font-size: 29px;
text-transform: uppercase;
letter-spacing: 3px;
line-height: 1.2em;
padding: 62px 10px 20px;
white-space: normal;
}
#kc-content {
width: 100%;
}
#kc-attempted-username {
font-size: 20px;
font-family: inherit;
font-weight: normal;
padding-right: 10px;
}
#kc-username {
text-align: center;
margin-bottom: -10px;
}
#kc-webauthn-settings-form {
padding-top: 8px;
}
#kc-content-wrapper {
margin-top: 20px;
}
#kc-form-wrapper {
margin-top: 10px;
}
#kc-info {
margin: 20px -40px -30px;
}
#kc-info-wrapper {
font-size: 13px;
padding: 15px 35px;
background-color: #f0f0f0;
}
#kc-form-options span {
display: block;
}
#kc-form-options .checkbox {
margin-top: 0;
color: #72767b;
}
#kc-terms-text {
margin-bottom: 20px;
}
#kc-registration {
margin-bottom: 0;
}
/* TOTP */
.subtitle {
text-align: right;
margin-top: 30px;
color: #909090;
}
.required {
color: #a30000; /* default - IE compatibility */
color: var(--pf-global--danger-color--200);
}
ol#kc-totp-settings {
margin: 0;
padding-left: 20px;
}
ul#kc-totp-supported-apps {
margin-bottom: 10px;
}
#kc-totp-secret-qr-code {
max-width: 150px;
max-height: 150px;
}
#kc-totp-secret-key {
background-color: #fff;
color: #333333;
font-size: 16px;
padding: 10px 0;
}
/* OAuth */
#kc-oauth h3 {
margin-top: 0;
}
#kc-oauth ul {
list-style: none;
padding: 0;
margin: 0;
}
#kc-oauth ul li {
border-top: 1px solid rgba(255, 255, 255, 0.1);
font-size: 12px;
padding: 10px 0;
}
#kc-oauth ul li:first-of-type {
border-top: 0;
}
#kc-oauth .kc-role {
display: inline-block;
width: 50%;
}
/* Code */
#kc-code textarea {
width: 100%;
height: 8em;
}
/* Social */
.kc-social-links {
margin-top: 20px;
}
.kc-social-provider-logo {
font-size: 23px;
width: 30px;
height: 25px;
float: left;
}
.kc-social-gray {
color: #737679; /* default - IE compatibility */
color: var(--pf-global--Color--200);
}
.kc-social-item {
margin-bottom: 0.5rem; /* default - IE compatibility */
margin-bottom: var(--pf-global--spacer--sm);
font-size: 15px;
text-align: center;
}
.kc-social-provider-name {
position: relative;
top: 3px;
}
.kc-social-icon-text {
left: -15px;
}
.kc-social-grid {
display: grid;
grid-column-gap: 10px;
grid-row-gap: 5px;
grid-column-end: span 6;
--pf-l-grid__item--GridColumnEnd: span 6;
}
.kc-social-grid .kc-social-icon-text {
left: -10px;
}
.kc-login-tooltip {
position: relative;
display: inline-block;
}
.kc-social-section {
text-align: center;
}
.kc-social-section hr {
margin-bottom: 10px;
}
.kc-login-tooltip .kc-tooltip-text {
top: -3px;
left: 160%;
background-color: black;
visibility: hidden;
color: #fff;
min-width: 130px;
text-align: center;
border-radius: 2px;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
padding: 5px;
position: absolute;
opacity: 0;
transition: opacity 0.5s;
}
/* Show tooltip */
.kc-login-tooltip:hover .kc-tooltip-text {
visibility: visible;
opacity: 0.7;
}
/* Arrow for tooltip */
.kc-login-tooltip .kc-tooltip-text::after {
content: " ";
position: absolute;
top: 15px;
right: 100%;
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent black transparent transparent;
}
@media (min-width: 768px) {
#kc-container-wrapper {
position: absolute;
width: 100%;
}
.login-pf .container {
padding-right: 80px;
}
#kc-locale {
position: relative;
text-align: right;
z-index: 9999;
}
}
@media (max-width: 767px) {
.login-pf body {
background: white;
}
#kc-header {
padding-left: 15px;
padding-right: 15px;
float: none;
text-align: left;
}
#kc-header-wrapper {
font-size: 16px;
font-weight: bold;
padding: 20px 60px 0 0;
color: #72767b;
letter-spacing: 0;
}
div.kc-logo-text {
margin: 0;
width: 150px;
height: 32px;
background-size: 100%;
}
#kc-form {
float: none;
}
#kc-info-wrapper {
border-top: 1px solid rgba(255, 255, 255, 0.1);
background-color: transparent;
}
.login-pf .container {
padding-top: 15px;
padding-bottom: 15px;
}
#kc-locale {
position: absolute;
width: 200px;
top: 20px;
right: 20px;
text-align: right;
z-index: 9999;
}
#kc-logo-wrapper {
background-size: 100px 21px;
height: 21px;
width: 100px;
margin: 20px 0 0 20px;
}
}
@media (min-height: 646px) {
#kc-container-wrapper {
bottom: 12%;
}
}
@media (max-height: 645px) {
#kc-container-wrapper {
padding-top: 50px;
top: 20%;
}
}
.card-pf form.form-actions .btn {
float: right;
margin-left: 10px;
}
#kc-form-buttons {
margin-top: 20px;
}
.login-pf-page .login-pf-brand {
margin-top: 20px;
max-width: 360px;
width: 40%;
}
/* Internet Explorer 11 compatibility workaround for select-authenticator screen */
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
.select-auth-box-parent {
border-top: 1px solid #f0f0f0;
padding-top: 1rem;
padding-bottom: 1rem;
cursor: pointer;
}
.select-auth-box-headline {
font-size: 16px;
color: #06c;
font-weight: bold;
}
.select-auth-box-desc {
font-size: 14px;
}
.pf-l-stack {
flex-basis: 100%;
}
}
/* End of IE11 workaround for select-authenticator screen */
.select-auth-box-arrow {
display: flex;
align-items: center;
margin-right: 2rem;
}
.select-auth-box-icon {
display: flex;
flex: 0 0 2em;
justify-content: center;
margin-right: 1rem;
margin-left: 3rem;
}
.select-auth-box-parent {
border-top: 1px solid var(--pf-global--palette--black-200);
padding-top: 1rem;
padding-bottom: 1rem;
cursor: pointer;
}
.select-auth-box-parent:hover {
background-color: #f7f8f8;
}
.select-auth-container {
padding-bottom: 0px !important;
}
.select-auth-box-headline {
font-size: var(--pf-global--FontSize--md);
color: var(--pf-global--primary-color--100);
font-weight: bold;
}
.select-auth-box-desc {
font-size: var(--pf-global--FontSize--sm);
}
.card-pf {
margin: 0 auto;
box-shadow: 0 2px 1px -1px rgb(0 0 0 / 20%), 0 1px 1px 0 rgb(0 0 0 / 14%),
0 1px 3px 0 rgb(0 0 0 / 12%);
padding: 0 20px;
max-width: 500px;
border-radius: 4px;
}
/*phone*/
@media (max-width: 767px) {
.login-pf-page .card-pf {
max-width: none;
margin-left: 0;
margin-right: 0;
padding-top: 0;
border-top: 0;
box-shadow: 0 0;
}
.kc-social-grid {
grid-column-end: 12;
--pf-l-grid__item--GridColumnEnd: span 12;
}
.kc-social-grid .kc-social-icon-text {
left: -15px;
}
}
.login-pf-page .login-pf-signup {
font-size: 15px;
color: #72767b;
}
#kc-content-wrapper .row {
margin-left: 0;
margin-right: 0;
}
.login-pf-page.login-pf-page-accounts {
margin-left: auto;
margin-right: auto;
}
.login-pf-page .btn-primary {
margin-top: 0;
}
.login-pf-page .list-view-pf .list-group-item {
border-bottom: 1px solid #ededed;
}
.login-pf-page .list-view-pf-description {
width: 100%;
}
#kc-form-login div.form-group:last-of-type,
#kc-register-form div.form-group:last-of-type,
#kc-update-profile-form div.form-group:last-of-type {
margin-bottom: 0px;
}
.no-bottom-margin {
margin-bottom: 0;
}
#kc-back {
margin-top: 5px;
}

View File

@ -0,0 +1,202 @@
/*Internet Explorer 11 compatibility workaround - IE does not support CSS variables */
@media all and (-ms-high-contrast: none),
(-ms-high-contrast: active) {
.pf-c-tile {
position: relative;
display: -ms-inline-grid;
display: inline-grid;
padding: 1.5rem 1.5rem 1.5rem 1.5rem;
margin-bottom: 0.25rem;
text-align: center;
cursor: pointer;
background-color: #fff;
grid-template-rows: -webkit-min-content;
-ms-grid-rows: -webkit-min-content;
-ms-grid-rows: min-content;
grid-template-rows: min-content;
}
.pf-c-tile::before {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
pointer-events: none;
content: "";
border: 1px solid #d2d2d2;
border-radius: 3px;
}
.pf-c-tile:hover {
border: 1px solid #06c;
border-radius: 3px;
}
.pf-c-tile:hover .pf-c-tile__title,
.pf-c-tile:hover .pf-c-tile__icon {
color: #06c;
}
.pf-c-tile.pf-m-selected .pf-c-tile__title,
.pf-c-tile.pf-m-selected .pf-c-tile__icon {
color: #06c;
}
.pf-c-tile.pf-m-selected {
border: 2px solid #06c;
border-radius: 3px;
}
.pf-c-tile.pf-m-disabled {
pointer-events: none;
}
.pf-c-tile__header {
display: flex;
align-items: center;
justify-content: center;
}
.pf-c-tile__header.pf-m-stacked {
flex-direction: column;
justify-content: initial;
}
.pf-c-tile__header.pf-m-stacked .pf-c-tile__icon {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0.25rem;
}
.pf-c-tile__title {
color: #6a6e73;
}
.pf-c-tile__body {
font-size: 0.75rem;
color: #6a6e73;
}
.pf-c-tile__icon {
margin-right: 0.5rem;
font-size: 1.5rem;
color: #6a6e73;
}
}
/*End of the IE11 workaround*/
.pf-c-tile {
--pf-c-tile--PaddingTop: var(--pf-global--spacer--lg);
--pf-c-tile--PaddingRight: var(--pf-global--spacer--lg);
--pf-c-tile--PaddingBottom: var(--pf-global--spacer--lg);
--pf-c-tile--PaddingLeft: var(--pf-global--spacer--lg);
--pf-c-tile--BackgroundColor: var(--pf-global--BackgroundColor--100);
--pf-c-tile--before--BorderColor: var(--pf-global--BorderColor--100);
--pf-c-tile--before--BorderWidth: var(--pf-global--BorderWidth--sm);
--pf-c-tile--before--BorderRadius: var(--pf-global--BorderRadius--sm);
--pf-c-tile--hover--before--BorderColor: var(--pf-global--primary-color--100);
--pf-c-tile--m-selected--before--BorderWidth: var(--pf-global--BorderWidth--md);
--pf-c-tile--m-selected--before--BorderColor: var(--pf-global--primary-color--100);
--pf-c-tile--focus--before--BorderWidth: var(--pf-global--BorderWidth--md);
--pf-c-tile--focus--before--BorderColor: var(--pf-global--primary-color--100);
--pf-c-tile--m-disabled--BackgroundColor: var(--pf-global--disabled-color--300);
--pf-c-tile__title--Color: var(--pf-global--Color--100);
--pf-c-tile--hover__title--Color: var(--pf-global--primary-color--100);
--pf-c-tile--m-selected__title--Color: var(--pf-global--primary-color--100);
--pf-c-tile--focus__title--Color: var(--pf-global--primary-color--100);
--pf-c-tile--m-disabled__title--Color: var(--pf-global--disabled-color--100);
--pf-c-tile__icon--MarginRight: var(--pf-global--spacer--sm);
--pf-c-tile__icon--FontSize: var(--pf-global--icon--FontSize--md);
--pf-c-tile__icon--Color: var(--pf-global--Color--100);
--pf-c-tile--hover__icon--Color: var(--pf-global--primary-color--100);
--pf-c-tile--m-selected__icon--Color: var(--pf-global--primary-color--100);
--pf-c-tile--m-disabled__icon--Color: var(--pf-global--disabled-color--100);
--pf-c-tile--focus__icon--Color: var(--pf-global--primary-color--100);
--pf-c-tile__header--m-stacked__icon--MarginBottom: var(--pf-global--spacer--xs);
--pf-c-tile__header--m-stacked__icon--FontSize: var(--pf-global--icon--FontSize--lg);
--pf-c-tile--m-display-lg__header--m-stacked__icon--FontSize: var(--pf-global--icon--FontSize--xl);
--pf-c-tile__body--Color: var(--pf-global--Color--100);
--pf-c-tile__body--FontSize: var(--pf-global--FontSize--xs);
--pf-c-tile--m-disabled__body--Color: var(--pf-global--disabled-color--100);
position: relative;
display: inline-grid;
padding: var(--pf-c-tile--PaddingTop) var(--pf-c-tile--PaddingRight) var(--pf-c-tile--PaddingBottom) var(--pf-c-tile--PaddingLeft);
margin-bottom: 0.25rem;
text-align: center;
cursor: pointer;
background-color: var(--pf-c-tile--BackgroundColor);
grid-template-rows: min-content;
}
.pf-c-tile::before {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
pointer-events: none;
content: "";
border: var(--pf-c-tile--before--BorderWidth) solid var(--pf-c-tile--before--BorderColor);
border-radius: var(--pf-c-tile--before--BorderRadius);
}
.pf-c-tile:hover {
--pf-c-tile__title--Color: var(--pf-c-tile--hover__title--Color);
--pf-c-tile__icon--Color: var(--pf-c-tile--hover__icon--Color);
--pf-c-tile--before--BorderColor: var(--pf-c-tile--hover--before--BorderColor);
}
.pf-c-tile.pf-m-selected {
--pf-c-tile__title--Color: var(--pf-c-tile--m-selected__title--Color);
--pf-c-tile__icon--Color: var(--pf-c-tile--m-selected__icon--Color);
--pf-c-tile--before--BorderWidth: var(--pf-c-tile--m-selected--before--BorderWidth);
--pf-c-tile--before--BorderColor: var(--pf-c-tile--m-selected--before--BorderColor);
}
.pf-c-tile:focus {
--pf-c-tile__title--Color: var(--pf-c-tile--focus__title--Color);
--pf-c-tile__icon--Color: var(--pf-c-tile--focus__icon--Color);
--pf-c-tile--before--BorderWidth: var(--pf-c-tile--focus--before--BorderWidth);
--pf-c-tile--before--BorderColor: var(--pf-c-tile--focus--before--BorderColor);
}
.pf-c-tile.pf-m-disabled {
--pf-c-tile--BackgroundColor: var(--pf-c-tile--m-disabled--BackgroundColor);
--pf-c-tile__title--Color: var(--pf-c-tile--m-disabled__title--Color);
--pf-c-tile__body--Color: var(--pf-c-tile--m-disabled__body--Color);
--pf-c-tile--before--BorderWidth: 0;
--pf-c-tile__icon--Color: var(--pf-c-tile--m-disabled__icon--Color);
pointer-events: none;
}
.pf-c-tile.pf-m-display-lg .pf-c-tile__header.pf-m-stacked {
--pf-c-tile__icon--FontSize: var(--pf-c-tile--m-display-lg__header--m-stacked__icon--FontSize);
}
.pf-c-tile__header {
display: flex;
align-items: center;
justify-content: center;
}
.pf-c-tile__header.pf-m-stacked {
--pf-c-tile__icon--MarginRight: 0;
--pf-c-tile__icon--FontSize: var(--pf-c-tile__header--m-stacked__icon--FontSize);
flex-direction: column;
justify-content: initial;
}
.pf-c-tile__header.pf-m-stacked .pf-c-tile__icon {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: var(--pf-c-tile__header--m-stacked__icon--MarginBottom);
}
.pf-c-tile__title {
color: var(--pf-c-tile__title--Color);
}
.pf-c-tile__body {
font-size: var(--pf-c-tile__body--FontSize);
color: var(--pf-c-tile__body--Color);
}
.pf-c-tile__icon {
margin-right: var(--pf-c-tile__icon--MarginRight);
font-size: var(--pf-c-tile__icon--FontSize);
color: var(--pf-c-tile__icon--Color);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,124 @@
parent=base
import=common/keycloak
styles=css/login.css css/tile.css
stylesCommon=web_modules/@fortawesome/fontawesome-free/css/icons/all.css web_modules/@patternfly/react-core/dist/styles/base.css web_modules/@patternfly/react-core/dist/styles/app.css node_modules/patternfly/dist/css/patternfly.min.css node_modules/patternfly/dist/css/patternfly-additions.min.css lib/pficon/pficon.css
scripts=js/material-components-web.min.js js/login.js
meta=viewport==width=device-width,initial-scale=1
kcHtmlClass=login-pf
kcLoginClass=login-pf-page
kcLogoLink=https://rickvanlieshout.com
kcLogoClass=login-pf-brand
kcContainerClass=container-fluid
kcContentClass=col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-6 col-lg-offset-3
kcHeaderClass=login-pf-page-header
kcFeedbackAreaClass=col-md-12
kcLocaleClass=col-xs-12 col-sm-1
## Alert
kcAlertClass=pf-c-alert pf-m-inline
kcAlertTitleClass=pf-c-alert__title kc-feedback-text
kcFormAreaClass=col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2
kcFormCardClass=card-pf
### Social providers
kcFormSocialAccountListClass=pf-c-login__main-footer-links kc-social-links
kcFormSocialAccountListGridClass=pf-l-grid kc-social-grid
kcFormSocialAccountListButtonClass=pf-c-button pf-m-control pf-m-block kc-social-item kc-social-gray
kcFormSocialAccountGridItem=pf-l-grid__item
kcFormSocialAccountNameClass=kc-social-provider-name
kcFormSocialAccountLinkClass=pf-c-login__main-footer-links-item-link
kcFormSocialAccountSectionClass=kc-social-section kc-social-gray
kcFormHeaderClass=login-pf-header
kcFeedbackErrorIcon=fa fa-fw fa-exclamation-circle
kcFeedbackWarningIcon=fa fa-fw fa-exclamation-triangle
kcFeedbackSuccessIcon=fa fa-fw fa-check-circle
kcFeedbackInfoIcon=fa fa-fw fa-info-circle
kcResetFlowIcon=pficon pficon-arrow fa
kcWebAuthnKeyIcon=pficon pficon-key
kcFormClass=form-horizontal
kcFormGroupClass=form-group
kcFormGroupErrorClass=has-error
kcLabelClass=pf-c-form__label pf-c-form__label-text
kcLabelWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
kcInputClass=pf-c-form-control
kcInputErrorMessageClass=pf-c-form__helper-text pf-m-error required kc-feedback-text
kcInputWrapperClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
kcFormOptionsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
kcFormButtonsClass=col-xs-12 col-sm-12 col-md-12 col-lg-12
kcFormSettingClass=login-pf-settings
kcTextareaClass=form-control
kcSignUpClass=login-pf-signup
kcInfoAreaClass=col-xs-12 col-sm-4 col-md-4 col-lg-5 details
##### css classes for form buttons
# main class used for all buttons
kcButtonClass=pf-c-button
# classes defining priority of the button - primary or default (there is typically only one priority button for the form)
kcButtonPrimaryClass=pf-m-primary
kcButtonDefaultClass=btn-default
# classes defining size of the button
kcButtonLargeClass=btn-lg
kcButtonBlockClass=pf-m-block
##### css classes for input
kcInputLargeClass=input-lg
##### css classes for form accessability
kcSrOnlyClass=sr-only
##### css classes for select-authenticator form
kcSelectAuthListClass=pf-l-stack select-auth-container
kcSelectAuthListItemClass=pf-l-stack__item select-auth-box-parent pf-l-split
kcSelectAuthListItemIconClass=pf-l-split__item select-auth-box-icon
kcSelectAuthListItemBodyClass=pf-l-split__item pf-l-stack
kcSelectAuthListItemHeadingClass=pf-l-stack__item select-auth-box-headline pf-c-title
kcSelectAuthListItemDescriptionClass=pf-l-stack__item select-auth-box-desc
kcSelectAuthListItemFillClass=pf-l-split__item pf-m-fill
kcSelectAuthListItemArrowClass=pf-l-split__item select-auth-box-arrow
kcSelectAuthListItemArrowIconClass=fa fa-angle-right fa-lg
##### css classes for the authenticators
kcAuthenticatorDefaultClass=fa list-view-pf-icon-lg
kcAuthenticatorPasswordClass=fa fa-unlock list-view-pf-icon-lg
kcAuthenticatorOTPClass=fa fa-mobile list-view-pf-icon-lg
kcAuthenticatorWebAuthnClass=fa fa-key list-view-pf-icon-lg
kcAuthenticatorWebAuthnPasswordlessClass=fa fa-key list-view-pf-icon-lg
##### css classes for the OTP Login Form
kcLoginOTPListClass=pf-c-tile otp-tile
kcLoginOTPListItemHeaderClass=pf-c-tile__header
kcLoginOTPListItemIconBodyClass=pf-c-tile__icon otp-tile-icon
kcLoginOTPListItemIconClass=fa fa-mobile
kcLoginOTPListItemTitleClass=pf-c-tile__title
##### css classes for identity providers logos
kcCommonLogoIdP=kc-social-provider-logo kc-social-gray
## Social
kcLogoIdP-facebook=fa fa-facebook
kcLogoIdP-google=fa fa-google
kcLogoIdP-github=fa fa-github
kcLogoIdP-linkedin=fa fa-linkedin
kcLogoIdP-instagram=fa fa-instagram
## windows instead of microsoft - not included in PF4
kcLogoIdP-microsoft=fa fa-windows
kcLogoIdP-bitbucket=fa fa-bitbucket
kcLogoIdP-gitlab=fa fa-gitlab
kcLogoIdP-paypal=fa fa-paypal
kcLogoIdP-stackoverflow=fa fa-stack-overflow
kcLogoIdP-twitter=fa fa-twitter
kcLogoIdP-openshift-v4=pf-icon pf-icon-openshift
kcLogoIdP-openshift-v3=pf-icon pf-icon-openshift

View File

@ -0,0 +1,49 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SSO mastermindzh.tech</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">
<link rel="shortcut icon" type="image/x-icon" href="${resourcesPath}/img/favicon.ico" />
<link rel="icon"
type="image/png"
href="${resourcesPath}/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="div-center">
<div class="content">
<div>
<img src ="${resourcesPath}/logo.png" alt = "logo" class="logo"/>
</div>
<hr />
<h3><a href="${adminUrl}"><img src="welcome-content/admin-console.png">Administration Console <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
<div class="description">
</div>
<h3><a href="/realms/public-tests/account/#/"><img src="welcome-content/user.png">Public login <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
<div class="description">
Login realm used for demos and temporary access
</div>
<h3><a href="https://rickvanlieshout.com"><img src="welcome-content/mail.png">Personal website <i class="fa fa-angle-right link" aria-hidden="true"></i></a></h3>
<div class="description">
Rick van Lieshout's (a.k.a mastermindzh) personal website
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,79 @@
body {
background: #fff url(../bg.jpg) no-repeat center bottom fixed;
background-size: cover;
}
.div-center {
width: 100%;
max-width: 500px;
height: 487px;
background-color: #fff;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
overflow: auto;
padding: 1em 2em;
display: table;
box-shadow: 0 11px 15px -7px rgb(0 0 0 / 20%),
0 24px 38px 3px rgb(0 0 0 / 14%), 0 9px 46px 8px rgb(0 0 0 / 12%);
}
.description {
margin-top: 10px;
}
.content {
padding-top: 10px;
}
img.doc-img {
width: auto;
height: 22px;
}
.link {
font-size: 16px;
vertical-align: baseline;
margin-left: 5px;
}
h3 {
font-weight: 550;
}
h3 a:link,
h3 a:visited {
color: #333;
font-weight: 550;
}
h3 a:hover,
h3 a:hover .link {
text-decoration: none;
color: #00659c;
}
h3 a img {
height: 30px;
margin-right: 10px;
width: auto;
}
h3 {
margin-bottom: 10px;
}
.logo {
max-width: 300px;
width: 100%;
}
@media (max-width: 500px) {
.div-center {
max-width: 100%;
height: 100%;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,7 @@
styles=css/welcome.css
import=common/keycloak
stylesCommon=node_modules/patternfly/dist/css/patternfly.css node_modules/patternfly/dist/css/patternfly-additions.css
documentationUrl=https://www.keycloak.org/documentation.html
displayCommunityLinks=true