Updates
277
.keycloakify/account/css/account.css
Normal file
@ -0,0 +1,277 @@
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #F9F9F9;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
header .navbar {
|
||||
margin-bottom: 0;
|
||||
min-height: inherit;
|
||||
}
|
||||
|
||||
.header .container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navbar-title {
|
||||
background-image: url('../img/logo.png');
|
||||
height: 25px;
|
||||
background-repeat: no-repeat;
|
||||
width: 123px;
|
||||
margin: 3px 10px 5px;
|
||||
text-indent: -99999px;
|
||||
}
|
||||
|
||||
.navbar-pf .navbar-utility {
|
||||
right: 20px;
|
||||
top: -34px !important;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.navbar-pf .navbar-utility > li > a {
|
||||
color: #fff !important;
|
||||
padding-bottom: 12px;
|
||||
padding-top: 11px;
|
||||
border-left: medium none;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
background-color: #fff;
|
||||
border-color: #CECECE;
|
||||
border-style: solid;
|
||||
border-width: 0 1px;
|
||||
height: 100%;
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
.margin-bottom {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
|
||||
.bs-sidebar {
|
||||
background-color: #f9f9f9;
|
||||
padding-top: 44px;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
z-index: 20;
|
||||
}
|
||||
.bs-sidebar ul {
|
||||
list-style: none;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.bs-sidebar ul li {
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: -1em;
|
||||
}
|
||||
.bs-sidebar ul li a {
|
||||
font-size: 14px;
|
||||
padding-left: 25px;
|
||||
color: #4d5258;
|
||||
line-height: 28px;
|
||||
display: block;
|
||||
border-width: 1px 0 1px 1px;
|
||||
border-style: solid;
|
||||
border-color: #f9f9f9;
|
||||
}
|
||||
.bs-sidebar ul li a:hover,
|
||||
.bs-sidebar ul li a:focus {
|
||||
text-decoration: none;
|
||||
color: #777777;
|
||||
border-right: 2px solid #aaa;
|
||||
}
|
||||
.bs-sidebar ul li.active a {
|
||||
background-color: #c7e5f0;
|
||||
border-color: #56bae0;
|
||||
font-weight: bold;
|
||||
background-image: url(../img/icon-sidebar-active.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
.bs-sidebar ul li.active a:hover {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
|
||||
.content-area h2 {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
font-weight: 100;
|
||||
font-size: 24px;
|
||||
margin-bottom: 25px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: right;
|
||||
margin-top: 30px;
|
||||
color: #909090;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #CB2915;
|
||||
}
|
||||
|
||||
|
||||
.alert {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.feedback-aligner .alert {
|
||||
background-position: 1.27273em center;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 2px;
|
||||
border-width: 1px;
|
||||
color: #4D5258;
|
||||
display: inline-block;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.4em;
|
||||
margin: 0;
|
||||
padding: 0.909091em 3.63636em;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
}
|
||||
.alert.alert-success {
|
||||
background-color: #E4F1E1;
|
||||
border-color: #4B9E39;
|
||||
}
|
||||
.alert.alert-error {
|
||||
background-color: #F8E7E7;
|
||||
border-color: #B91415;
|
||||
}
|
||||
.alert.alert-warning {
|
||||
background-color: #FEF1E9;
|
||||
border-color: #F17528;
|
||||
}
|
||||
.alert.alert-info {
|
||||
background-color: #E4F3FA;
|
||||
border-color: #5994B2;
|
||||
}
|
||||
|
||||
.form-horizontal {
|
||||
border-top: 1px solid #E9E8E8;
|
||||
padding-top: 23px;
|
||||
}
|
||||
|
||||
.form-horizontal .control-label {
|
||||
color: #909090;
|
||||
line-height: 1.4em;
|
||||
padding-top: 5px;
|
||||
position: relative;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.control-label + .required {
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
#kc-form-buttons {
|
||||
text-align: right;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#kc-form-buttons .btn-primary {
|
||||
float: right;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* Authenticator page */
|
||||
|
||||
ol {
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
ol li {
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
ol li img {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
|
||||
hr + .form-horizontal {
|
||||
border: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.kc-dropdown{
|
||||
position: relative;
|
||||
}
|
||||
.kc-dropdown > a{
|
||||
display:block;
|
||||
padding: 11px 10px 12px;
|
||||
line-height: 12px;
|
||||
font-size: 12px;
|
||||
color: #fff !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
.kc-dropdown > a::after{
|
||||
content: "\2c5";
|
||||
margin-left: 4px;
|
||||
}
|
||||
.kc-dropdown:hover > a{
|
||||
background-color: rgba(0,0,0,0.2);
|
||||
}
|
||||
.kc-dropdown ul li a{
|
||||
padding: 1px 11px;
|
||||
font-size: 12px;
|
||||
color: #000 !important;
|
||||
border: 1px solid #fff;
|
||||
text-decoration: none;
|
||||
display:block;
|
||||
line-height: 20px;
|
||||
}
|
||||
.kc-dropdown ul li a:hover{
|
||||
color: #4d5258;
|
||||
background-color: #d4edfa;
|
||||
border-color: #b3d3e7;
|
||||
}
|
||||
.kc-dropdown ul{
|
||||
position: absolute;
|
||||
z-index: 2000;
|
||||
list-style:none;
|
||||
display:none;
|
||||
padding: 5px 0px;
|
||||
margin: 0px;
|
||||
background-color: #fff !important;
|
||||
border: 1px solid #b6b6b6;
|
||||
border-radius: 1px;
|
||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
background-clip: padding-box;
|
||||
min-width: 100px;
|
||||
}
|
||||
.kc-dropdown:hover ul{
|
||||
display:block;
|
||||
}
|
||||
|
||||
|
||||
#kc-totp-secret-key {
|
||||
border: 1px solid #eee;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
margin: 50px 0;
|
||||
}
|
BIN
.keycloakify/account/img/icon-sidebar-active.png
Normal file
After Width: | Height: | Size: 202 B |
BIN
.keycloakify/account/img/keycloak-logo.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
.keycloakify/account/img/logo.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
.keycloakify/account/resources-common/img/favicon.ico
Normal file
After Width: | Height: | Size: 627 B |
5
.keycloakify/account/resources-common/node_modules/patternfly/dist/css/patternfly-additions.min.css
generated
vendored
Normal file
8
.keycloakify/account/resources-common/node_modules/patternfly/dist/css/patternfly.min.css
generated
vendored
Normal file
BIN
.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Light-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Regular-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Semibold-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.ttf
generated
vendored
Normal file
BIN
.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.woff
generated
vendored
Normal file
629
.keycloakify/login/css/login.css
Normal file
@ -0,0 +1,629 @@
|
||||
/* Patternfly CSS places a "bg-login.jpg" as the background on this ".login-pf" class.
|
||||
This clashes with the "keycloak-bg.png' background defined on the body below.
|
||||
Therefore the Patternfly background must be set to none. */
|
||||
.login-pf {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.login-pf body {
|
||||
background: url("../img/keycloak-bg.png") no-repeat center center fixed;
|
||||
background-size: cover;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
textarea.pf-c-form-control {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.pf-c-alert__title {
|
||||
font-size: var(--pf-global--FontSize--xs);
|
||||
}
|
||||
|
||||
p.instruction {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.pf-c-button.pf-m-control {
|
||||
border-color: rgba(230, 230, 230, 0.5);
|
||||
}
|
||||
|
||||
h1#kc-page-title {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#kc-locale ul {
|
||||
background-color: var(--pf-global--BackgroundColor--100);
|
||||
display: none;
|
||||
top: 20px;
|
||||
min-width: 100px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#kc-locale-dropdown{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#kc-locale-dropdown:hover ul {
|
||||
display:block;
|
||||
}
|
||||
|
||||
#kc-locale-dropdown a {
|
||||
color: var(--pf-global--Color--200);
|
||||
text-align: right;
|
||||
font-size: var(--pf-global--FontSize--sm);
|
||||
}
|
||||
|
||||
#kc-locale-dropdown button {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
color: var(--pf-global--Color--200);
|
||||
text-align: right;
|
||||
font-size: var(--pf-global--FontSize--sm);
|
||||
}
|
||||
|
||||
button#kc-current-locale-link::after {
|
||||
content: "\2c5";
|
||||
margin-left: var(--pf-global--spacer--xs)
|
||||
}
|
||||
|
||||
.login-pf .container {
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.login-pf a:hover {
|
||||
color: #0099d3;
|
||||
}
|
||||
|
||||
#kc-logo {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.kc-logo-text {
|
||||
background-image: url(../img/keycloak-logo-text.png);
|
||||
background-repeat: no-repeat;
|
||||
height: 63px;
|
||||
width: 300px;
|
||||
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-form-webauthn .select-auth-box-parent {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#kc-form-webauthn .select-auth-box-desc {
|
||||
color: var(--pf-global--palette--black-600);
|
||||
}
|
||||
|
||||
#kc-form-webauthn .select-auth-box-headline {
|
||||
color: var(--pf-global--Color--300);
|
||||
}
|
||||
|
||||
#kc-form-webauthn .select-auth-box-icon {
|
||||
flex: 0 0 3em;
|
||||
}
|
||||
|
||||
#kc-form-webauthn .select-auth-box-icon-properties {
|
||||
margin-top: 10px;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
#kc-form-webauthn .select-auth-box-icon-properties.unknown-transport-class {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
#kc-form-webauthn .pf-l-stack__item {
|
||||
margin: -1px 0;
|
||||
}
|
||||
|
||||
#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-terms-text {
|
||||
max-height: 100px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#kc-registration {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* TOTP */
|
||||
|
||||
.subtitle {
|
||||
text-align: right;
|
||||
margin-top: 30px;
|
||||
color: #909090;
|
||||
}
|
||||
|
||||
.required {
|
||||
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-links li {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.kc-social-provider-logo {
|
||||
font-size: 23px;
|
||||
width: 30px;
|
||||
height: 25px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.kc-social-gray {
|
||||
color: var(--pf-global--Color--200);
|
||||
}
|
||||
|
||||
.kc-social-gray h2 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.kc-social-item {
|
||||
margin-bottom: var(--pf-global--spacer--sm);
|
||||
font-size: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.kc-social-provider-name {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
@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%;
|
||||
}
|
||||
|
||||
.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;
|
||||
text-align: left;
|
||||
align-items: unset;
|
||||
background-color: unset;
|
||||
border-right: unset;
|
||||
border-bottom: unset;
|
||||
border-left: unset;
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
.select-auth-box-paragraph {
|
||||
text-align: center;
|
||||
font-size: var(--pf-global--FontSize--md);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.card-pf {
|
||||
margin: 0 auto;
|
||||
box-shadow: var(--pf-global--BoxShadow--lg);
|
||||
padding: 0 20px;
|
||||
max-width: 500px;
|
||||
border-top: 4px solid;
|
||||
border-color: var(--pf-global--primary-color--100);
|
||||
}
|
||||
|
||||
/*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,
|
||||
#kc-update-email-form div.form-group:last-of-type{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.no-bottom-margin {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#kc-back {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/* Recovery codes */
|
||||
.kc-recovery-codes-warning {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.kc-recovery-codes-warning .pf-c-alert__description p {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.kc-recovery-codes-list {
|
||||
list-style: none;
|
||||
columns: 2;
|
||||
margin: 16px 0;
|
||||
padding: 16px 16px 8px 16px;
|
||||
border: 1px solid #D2D2D2;
|
||||
}
|
||||
.kc-recovery-codes-list li {
|
||||
margin-bottom: 8px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.kc-recovery-codes-list li span {
|
||||
color: #6A6E73;
|
||||
width: 16px;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.kc-recovery-codes-actions {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.kc-recovery-codes-actions button {
|
||||
padding-left: 0;
|
||||
}
|
||||
.kc-recovery-codes-actions button i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.kc-recovery-codes-confirmation {
|
||||
align-items: baseline;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
#certificate_subjectDN {
|
||||
overflow-wrap: break-word
|
||||
}
|
||||
/* End Recovery codes */
|
BIN
.keycloakify/login/img/feedback-error-arrow-down.png
Normal file
After Width: | Height: | Size: 513 B |
BIN
.keycloakify/login/img/feedback-error-sign.png
Normal file
After Width: | Height: | Size: 343 B |
BIN
.keycloakify/login/img/feedback-success-arrow-down.png
Normal file
After Width: | Height: | Size: 678 B |
BIN
.keycloakify/login/img/feedback-success-sign.png
Normal file
After Width: | Height: | Size: 410 B |
BIN
.keycloakify/login/img/feedback-warning-arrow-down.png
Normal file
After Width: | Height: | Size: 513 B |
BIN
.keycloakify/login/img/feedback-warning-sign.png
Normal file
After Width: | Height: | Size: 646 B |
BIN
.keycloakify/login/img/keycloak-bg.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
.keycloakify/login/img/keycloak-logo-text.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
.keycloakify/login/img/keycloak-logo.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
49
.keycloakify/login/js/authChecker.js
Normal file
@ -0,0 +1,49 @@
|
||||
const CHECK_INTERVAL_MILLISECS = 2000;
|
||||
const initialSession = getSession();
|
||||
|
||||
let timeout;
|
||||
|
||||
// Remove the timeout when unloading to avoid execution of the
|
||||
// checkCookiesAndSetTimer when the page is already submitted
|
||||
addEventListener("beforeunload", () => {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
export function checkCookiesAndSetTimer(loginRestartUrl) {
|
||||
if (initialSession) {
|
||||
// We started with a session, so there is nothing to do, exit.
|
||||
return;
|
||||
}
|
||||
|
||||
const session = getSession();
|
||||
|
||||
if (!session) {
|
||||
// The session is not present, check again later.
|
||||
timeout = setTimeout(
|
||||
() => checkCookiesAndSetTimer(loginRestartUrl),
|
||||
CHECK_INTERVAL_MILLISECS,
|
||||
);
|
||||
} else {
|
||||
// Redirect to the login restart URL. This can typically automatically login user due the SSO
|
||||
location.href = loginRestartUrl;
|
||||
}
|
||||
}
|
||||
|
||||
function getSession() {
|
||||
return getCookieByName("KEYCLOAK_SESSION");
|
||||
}
|
||||
|
||||
function getCookieByName(name) {
|
||||
for (const cookie of document.cookie.split(";")) {
|
||||
const [key, value] = cookie.split("=").map((value) => value.trim());
|
||||
if (key === name) {
|
||||
return value.startsWith('"') && value.endsWith('"')
|
||||
? value.slice(1, -1)
|
||||
: value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
48
.keycloakify/login/js/common.js
Normal file
@ -0,0 +1,48 @@
|
||||
export const formatNumber = (input, format) => {
|
||||
if (!input) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// array holding the patterns for the number of expected digits in each part
|
||||
const digitPattern = format.match(/{\d+}/g);
|
||||
|
||||
if (!digitPattern) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// calculate the maximum size of the given pattern based on the sum of the expected digits
|
||||
const maxSize = digitPattern.reduce((total, p) => total + parseInt(p.replace("{", "").replace("}", "")), 0)
|
||||
|
||||
// keep only digits
|
||||
let rawValue = input.replace(/\D+/g, '');
|
||||
|
||||
// make sure the value is a number
|
||||
if (parseInt(rawValue) != rawValue) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// make sure the number of digits does not exceed the maximum size
|
||||
if (rawValue.length > maxSize) {
|
||||
rawValue = rawValue.substring(0, maxSize);
|
||||
}
|
||||
|
||||
// build the regex based based on the expected digits in each part
|
||||
const formatter = digitPattern.reduce((result, p) => result + `(\\d${p})`, "^");
|
||||
|
||||
// if the current digits match the pattern we have each group of digits in an array
|
||||
let digits = new RegExp(formatter).exec(rawValue);
|
||||
|
||||
// no match, return the raw value without any format
|
||||
if (!digits) {
|
||||
return input;
|
||||
}
|
||||
|
||||
let result = format;
|
||||
|
||||
// finally format the current digits accordingly to the given format
|
||||
for (let i = 0; i < digitPattern.length; i++) {
|
||||
result = result.replace(digitPattern[i], digits[i + 1]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
106
.keycloakify/login/js/kcMultivalued.js
Normal file
@ -0,0 +1,106 @@
|
||||
const DATA_KC_MULTIVALUED = 'data-kcMultivalued';
|
||||
const KC_ADD_ACTION_PREFIX = "kc-add-";
|
||||
const KC_REMOVE_ACTION_PREFIX = "kc-remove-";
|
||||
const KC_ACTION_CLASS = "pf-c-button pf-m-inline pf-m-link";
|
||||
|
||||
function createAddAction(element) {
|
||||
const action = createAction("Add value",
|
||||
KC_ADD_ACTION_PREFIX,
|
||||
element,
|
||||
() => {
|
||||
const name = element.getAttribute("name");
|
||||
const elements = getInputElementsByName().get(name);
|
||||
const length = elements.length;
|
||||
|
||||
if (length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastNode = elements[length - 1];
|
||||
const newNode = lastNode.cloneNode(true);
|
||||
newNode.setAttribute("id", name + "-" + elements.length);
|
||||
newNode.value = "";
|
||||
lastNode.after(newNode);
|
||||
|
||||
render();
|
||||
});
|
||||
|
||||
element.after(action);
|
||||
}
|
||||
|
||||
function createRemoveAction(element, isLastElement) {
|
||||
let text = "Remove";
|
||||
|
||||
if (isLastElement) {
|
||||
text = text + " | ";
|
||||
}
|
||||
|
||||
const action = createAction(text, KC_REMOVE_ACTION_PREFIX, element, () => {
|
||||
removeActions(element);
|
||||
element.remove();
|
||||
render();
|
||||
});
|
||||
|
||||
element.insertAdjacentElement('afterend', action);
|
||||
}
|
||||
|
||||
function getInputElementsByName() {
|
||||
const selector = document.querySelectorAll(`[${DATA_KC_MULTIVALUED}]`);
|
||||
const elementsByName = new Map();
|
||||
|
||||
for (let element of Array.from(selector.values())) {
|
||||
let name = element.getAttribute("name");
|
||||
let elements = elementsByName.get(name);
|
||||
|
||||
if (!elements) {
|
||||
elements = [];
|
||||
elementsByName.set(name, elements);
|
||||
}
|
||||
|
||||
elements.push(element);
|
||||
}
|
||||
|
||||
return elementsByName;
|
||||
}
|
||||
|
||||
function removeActions(element) {
|
||||
for (let actionPrefix of [KC_ADD_ACTION_PREFIX, KC_REMOVE_ACTION_PREFIX]) {
|
||||
const action = document.getElementById(actionPrefix + element.getAttribute("id"));
|
||||
|
||||
if (action) {
|
||||
action.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createAction(text, type, element, onClick) {
|
||||
const action = document.createElement("button")
|
||||
action.setAttribute("id", type + element.getAttribute("id"));
|
||||
action.setAttribute("type", "button");
|
||||
action.innerText = text;
|
||||
action.setAttribute("class", KC_ACTION_CLASS);
|
||||
action.addEventListener("click", onClick);
|
||||
return action;
|
||||
}
|
||||
|
||||
function render() {
|
||||
getInputElementsByName().forEach((elements, name) => {
|
||||
elements.forEach((element, index) => {
|
||||
removeActions(element);
|
||||
|
||||
element.setAttribute("id", name + "-" + index);
|
||||
|
||||
const lastNode = element === elements[elements.length - 1];
|
||||
|
||||
if (lastNode) {
|
||||
createAddAction(element);
|
||||
}
|
||||
|
||||
if (elements.length > 1) {
|
||||
createRemoveAction(element, lastNode);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render();
|
21
.keycloakify/login/js/kcNumberFormat.js
Normal file
@ -0,0 +1,21 @@
|
||||
// @ts-check
|
||||
import { formatNumber } from "./common.js";
|
||||
import { registerElementAnnotatedBy } from "./userProfile.js";
|
||||
|
||||
const KC_NUMBER_FORMAT = "kcNumberFormat";
|
||||
|
||||
registerElementAnnotatedBy({
|
||||
name: KC_NUMBER_FORMAT,
|
||||
onAdd(element) {
|
||||
const formatValue = () => {
|
||||
const format = element.getAttribute(`data-${KC_NUMBER_FORMAT}`);
|
||||
element.value = formatNumber(element.value, format);
|
||||
};
|
||||
|
||||
element.addEventListener("keyup", formatValue);
|
||||
|
||||
formatValue();
|
||||
|
||||
return () => element.removeEventListener("keyup", formatValue);
|
||||
},
|
||||
});
|
19
.keycloakify/login/js/kcNumberUnFormat.js
Normal file
@ -0,0 +1,19 @@
|
||||
// @ts-check
|
||||
import { formatNumber } from "./common.js";
|
||||
import { registerElementAnnotatedBy } from "./userProfile.js";
|
||||
|
||||
const KC_NUMBER_UNFORMAT = 'kcNumberUnFormat';
|
||||
|
||||
registerElementAnnotatedBy({
|
||||
name: KC_NUMBER_UNFORMAT,
|
||||
onAdd(element) {
|
||||
for (let form of document.forms) {
|
||||
form.addEventListener('submit', (event) => {
|
||||
const rawFormat = element.getAttribute(`data-${KC_NUMBER_UNFORMAT}`);
|
||||
if (rawFormat) {
|
||||
element.value = formatNumber(element.value, rawFormat);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
315
.keycloakify/login/js/menu-button-links.js
Normal file
@ -0,0 +1,315 @@
|
||||
// @ts-check
|
||||
/*
|
||||
* This content is licensed according to the W3C Software License at
|
||||
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
||||
*
|
||||
* File: menu-button-links.js
|
||||
*
|
||||
* Desc: Creates a menu button that opens a menu of links
|
||||
*
|
||||
* Modified by Peter Keuter to adhere to the coding standards of Keycloak
|
||||
* Original file: https://www.w3.org/WAI/content-assets/wai-aria-practices/patterns/menu-button/examples/js/menu-button-links.js
|
||||
* Source: https://www.w3.org/TR/wai-aria-practices/examples/menu-button/menu-button-links.html
|
||||
*/
|
||||
|
||||
class MenuButtonLinks {
|
||||
constructor(domNode) {
|
||||
this.domNode = domNode;
|
||||
this.buttonNode = domNode.querySelector("button");
|
||||
this.menuNode = domNode.querySelector('[role="menu"]');
|
||||
this.menuitemNodes = [];
|
||||
this.firstMenuitem = false;
|
||||
this.lastMenuitem = false;
|
||||
this.firstChars = [];
|
||||
|
||||
this.buttonNode.addEventListener("keydown", (e) => this.onButtonKeydown(e));
|
||||
this.buttonNode.addEventListener("click", (e) => this.onButtonClick(e));
|
||||
|
||||
const nodes = domNode.querySelectorAll('[role="menuitem"]');
|
||||
|
||||
for (const menuitem of nodes) {
|
||||
this.menuitemNodes.push(menuitem);
|
||||
menuitem.tabIndex = -1;
|
||||
this.firstChars.push(menuitem.textContent.trim()[0].toLowerCase());
|
||||
|
||||
menuitem.addEventListener("keydown", (e) => this.onMenuitemKeydown(e));
|
||||
|
||||
menuitem.addEventListener("mouseover", (e) =>
|
||||
this.onMenuitemMouseover(e)
|
||||
);
|
||||
|
||||
if (!this.firstMenuitem) {
|
||||
this.firstMenuitem = menuitem;
|
||||
}
|
||||
this.lastMenuitem = menuitem;
|
||||
}
|
||||
|
||||
domNode.addEventListener("focusin", () => this.onFocusin());
|
||||
domNode.addEventListener("focusout", () => this.onFocusout());
|
||||
|
||||
window.addEventListener(
|
||||
"mousedown",
|
||||
(e) => this.onBackgroundMousedown(e),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
setFocusToMenuitem = (newMenuitem) =>
|
||||
this.menuitemNodes.forEach((item) => {
|
||||
if (item === newMenuitem) {
|
||||
item.tabIndex = 0;
|
||||
newMenuitem.focus();
|
||||
} else {
|
||||
item.tabIndex = -1;
|
||||
}
|
||||
});
|
||||
|
||||
setFocusToFirstMenuitem = () => this.setFocusToMenuitem(this.firstMenuitem);
|
||||
|
||||
setFocusToLastMenuitem = () => this.setFocusToMenuitem(this.lastMenuitem);
|
||||
|
||||
setFocusToPreviousMenuitem = (currentMenuitem) => {
|
||||
let newMenuitem, index;
|
||||
|
||||
if (currentMenuitem === this.firstMenuitem) {
|
||||
newMenuitem = this.lastMenuitem;
|
||||
} else {
|
||||
index = this.menuitemNodes.indexOf(currentMenuitem);
|
||||
newMenuitem = this.menuitemNodes[index - 1];
|
||||
}
|
||||
|
||||
this.setFocusToMenuitem(newMenuitem);
|
||||
|
||||
return newMenuitem;
|
||||
};
|
||||
|
||||
setFocusToNextMenuitem = (currentMenuitem) => {
|
||||
let newMenuitem, index;
|
||||
|
||||
if (currentMenuitem === this.lastMenuitem) {
|
||||
newMenuitem = this.firstMenuitem;
|
||||
} else {
|
||||
index = this.menuitemNodes.indexOf(currentMenuitem);
|
||||
newMenuitem = this.menuitemNodes[index + 1];
|
||||
}
|
||||
this.setFocusToMenuitem(newMenuitem);
|
||||
|
||||
return newMenuitem;
|
||||
};
|
||||
|
||||
setFocusByFirstCharacter = (currentMenuitem, char) => {
|
||||
let start, index;
|
||||
|
||||
if (char.length > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
char = char.toLowerCase();
|
||||
|
||||
// Get start index for search based on position of currentItem
|
||||
start = this.menuitemNodes.indexOf(currentMenuitem) + 1;
|
||||
if (start >= this.menuitemNodes.length) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
// Check remaining slots in the menu
|
||||
index = this.firstChars.indexOf(char, start);
|
||||
|
||||
// If not found in remaining slots, check from beginning
|
||||
if (index === -1) {
|
||||
index = this.firstChars.indexOf(char, 0);
|
||||
}
|
||||
|
||||
// If match was found...
|
||||
if (index > -1) {
|
||||
this.setFocusToMenuitem(this.menuitemNodes[index]);
|
||||
}
|
||||
};
|
||||
|
||||
// Utilities
|
||||
|
||||
getIndexFirstChars = (startIndex, char) => {
|
||||
for (let i = startIndex; i < this.firstChars.length; i++) {
|
||||
if (char === this.firstChars[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Popup menu methods
|
||||
|
||||
openPopup = () => {
|
||||
this.menuNode.style.display = "block";
|
||||
this.buttonNode.setAttribute("aria-expanded", "true");
|
||||
};
|
||||
|
||||
closePopup = () => {
|
||||
if (this.isOpen()) {
|
||||
this.buttonNode.setAttribute("aria-expanded", "false");
|
||||
this.menuNode.style.removeProperty("display");
|
||||
}
|
||||
};
|
||||
|
||||
isOpen = () => {
|
||||
return this.buttonNode.getAttribute("aria-expanded") === "true";
|
||||
};
|
||||
|
||||
// Menu event handlers
|
||||
|
||||
onFocusin = () => {
|
||||
this.domNode.classList.add("focus");
|
||||
};
|
||||
|
||||
onFocusout = () => {
|
||||
this.domNode.classList.remove("focus");
|
||||
};
|
||||
|
||||
onButtonKeydown = (event) => {
|
||||
const key = event.key;
|
||||
let flag = false;
|
||||
|
||||
switch (key) {
|
||||
case " ":
|
||||
case "Enter":
|
||||
case "ArrowDown":
|
||||
case "Down":
|
||||
this.openPopup();
|
||||
this.setFocusToFirstMenuitem();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case "Esc":
|
||||
case "Escape":
|
||||
this.closePopup();
|
||||
this.buttonNode.focus();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case "Up":
|
||||
case "ArrowUp":
|
||||
this.openPopup();
|
||||
this.setFocusToLastMenuitem();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
onButtonClick(event) {
|
||||
if (this.isOpen()) {
|
||||
this.closePopup();
|
||||
this.buttonNode.focus();
|
||||
} else {
|
||||
this.openPopup();
|
||||
this.setFocusToFirstMenuitem();
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
onMenuitemKeydown(event) {
|
||||
const tgt = event.currentTarget;
|
||||
const key = event.key;
|
||||
let flag = false;
|
||||
|
||||
const isPrintableCharacter = (str) => str.length === 1 && str.match(/\S/);
|
||||
|
||||
if (event.ctrlKey || event.altKey || event.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.shiftKey) {
|
||||
if (isPrintableCharacter(key)) {
|
||||
this.setFocusByFirstCharacter(tgt, key);
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (event.key === "Tab") {
|
||||
this.buttonNode.focus();
|
||||
this.closePopup();
|
||||
flag = true;
|
||||
}
|
||||
} else {
|
||||
switch (key) {
|
||||
case " ":
|
||||
window.location.href = tgt.href;
|
||||
break;
|
||||
|
||||
case "Esc":
|
||||
case "Escape":
|
||||
this.closePopup();
|
||||
this.buttonNode.focus();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case "Up":
|
||||
case "ArrowUp":
|
||||
this.setFocusToPreviousMenuitem(tgt);
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case "ArrowDown":
|
||||
case "Down":
|
||||
this.setFocusToNextMenuitem(tgt);
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case "Home":
|
||||
case "PageUp":
|
||||
this.setFocusToFirstMenuitem();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case "End":
|
||||
case "PageDown":
|
||||
this.setFocusToLastMenuitem();
|
||||
flag = true;
|
||||
break;
|
||||
|
||||
case "Tab":
|
||||
this.closePopup();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isPrintableCharacter(key)) {
|
||||
this.setFocusByFirstCharacter(tgt, key);
|
||||
flag = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
onMenuitemMouseover(event) {
|
||||
const tgt = event.currentTarget;
|
||||
tgt.focus();
|
||||
}
|
||||
|
||||
onBackgroundMousedown(event) {
|
||||
if (!this.domNode.contains(event.target)) {
|
||||
if (this.isOpen()) {
|
||||
this.closePopup();
|
||||
this.buttonNode.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const menuButtons = document.querySelectorAll(".menu-button-links");
|
||||
for (const button of menuButtons) {
|
||||
new MenuButtonLinks(button);
|
||||
}
|
79
.keycloakify/login/js/passkeysConditionalAuth.js
Normal file
@ -0,0 +1,79 @@
|
||||
import { base64url } from "rfc4648";
|
||||
import { returnSuccess, returnFailure } from "./webauthnAuthenticate.js";
|
||||
|
||||
export function initAuthenticate(input) {
|
||||
// Check if WebAuthn is supported by this browser
|
||||
if (!window.PublicKeyCredential) {
|
||||
returnFailure(input.errmsg);
|
||||
return;
|
||||
}
|
||||
if (input.isUserIdentified || typeof PublicKeyCredential.isConditionalMediationAvailable === "undefined") {
|
||||
document.getElementById("kc-form-passkey-button").style.display = 'block';
|
||||
} else {
|
||||
tryAutoFillUI(input);
|
||||
}
|
||||
}
|
||||
|
||||
function doAuthenticate(input) {
|
||||
// Check if WebAuthn is supported by this browser
|
||||
if (!window.PublicKeyCredential) {
|
||||
returnFailure(input.errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
const publicKey = {
|
||||
rpId : input.rpId,
|
||||
challenge: base64url.parse(input.challenge, { loose: true })
|
||||
};
|
||||
|
||||
publicKey.allowCredentials = !input.isUserIdentified ? [] : getAllowCredentials();
|
||||
|
||||
if (input.createTimeout !== 0) {
|
||||
publicKey.timeout = input.createTimeout * 1000;
|
||||
}
|
||||
|
||||
if (input.userVerification !== 'not specified') {
|
||||
publicKey.userVerification = input.userVerification;
|
||||
}
|
||||
|
||||
return navigator.credentials.get({
|
||||
publicKey: publicKey,
|
||||
...input.additionalOptions
|
||||
});
|
||||
}
|
||||
|
||||
async function tryAutoFillUI(input) {
|
||||
const isConditionalMediationAvailable = await PublicKeyCredential.isConditionalMediationAvailable();
|
||||
if (isConditionalMediationAvailable) {
|
||||
document.getElementById("kc-form-login").style.display = "block";
|
||||
input.additionalOptions = { mediation: 'conditional'};
|
||||
try {
|
||||
const result = await doAuthenticate(input);
|
||||
returnSuccess(result);
|
||||
} catch (error) {
|
||||
returnFailure(error);
|
||||
}
|
||||
} else {
|
||||
document.getElementById("kc-form-passkey-button").style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
function getAllowCredentials() {
|
||||
const allowCredentials = [];
|
||||
const authnUse = document.forms['authn_select'].authn_use_chk;
|
||||
if (authnUse !== undefined) {
|
||||
if (authnUse.length === undefined) {
|
||||
allowCredentials.push({
|
||||
id: base64url.parse(authnUse.value, {loose: true}),
|
||||
type: 'public-key',
|
||||
});
|
||||
} else {
|
||||
authnUse.forEach((entry) =>
|
||||
allowCredentials.push({
|
||||
id: base64url.parse(entry.value, {loose: true}),
|
||||
type: 'public-key',
|
||||
}));
|
||||
}
|
||||
}
|
||||
return allowCredentials;
|
||||
}
|
15
.keycloakify/login/js/passwordVisibility.js
Normal file
@ -0,0 +1,15 @@
|
||||
const toggle = (button) => {
|
||||
const passwordElement = document.getElementById(button.getAttribute('aria-controls'));
|
||||
if (passwordElement.type === "password") {
|
||||
passwordElement.type = "text";
|
||||
button.children.item(0).className = button.dataset.iconHide;
|
||||
button.setAttribute("aria-label", button.dataset.labelHide);
|
||||
} else if(passwordElement.type === "text") {
|
||||
passwordElement.type = "password";
|
||||
button.children.item(0).className = button.dataset.iconShow;
|
||||
button.setAttribute("aria-label", button.dataset.labelShow);
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-password-toggle]')
|
||||
.forEach(button => button.onclick = () => toggle(button));
|
71
.keycloakify/login/js/userProfile.js
Normal file
@ -0,0 +1,71 @@
|
||||
// @ts-check
|
||||
/**
|
||||
* @typedef {Object} AnnotationDescriptor
|
||||
* @property {string} name - The name of the field to register (e.g. `numberFormat`).
|
||||
* @property {(element: HTMLElement) => (() => void) | void} onAdd - The function to call when a new element is added to the DOM.
|
||||
*/
|
||||
|
||||
const observer = new MutationObserver(onMutate);
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
/** @type {AnnotationDescriptor[]} */
|
||||
const descriptors = [];
|
||||
|
||||
/** @type {WeakMap<HTMLElement, () => void>} */
|
||||
const cleanupFunctions = new WeakMap();
|
||||
|
||||
/**
|
||||
* @param {AnnotationDescriptor} descriptor
|
||||
*/
|
||||
export function registerElementAnnotatedBy(descriptor) {
|
||||
descriptors.push(descriptor);
|
||||
|
||||
document.querySelectorAll(`[data-${descriptor.name}]`).forEach((element) => {
|
||||
if (element instanceof HTMLElement) {
|
||||
handleNewElement(element, descriptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {MutationCallback}
|
||||
*/
|
||||
function onMutate(mutations) {
|
||||
const removedNodes = mutations.flatMap((mutation) => Array.from(mutation.removedNodes));
|
||||
|
||||
for (const node of removedNodes) {
|
||||
if (!(node instanceof HTMLElement)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const handleRemovedElement = cleanupFunctions.get(node);
|
||||
|
||||
if (handleRemovedElement) {
|
||||
handleRemovedElement();
|
||||
}
|
||||
|
||||
cleanupFunctions.delete(node);
|
||||
}
|
||||
|
||||
const addedNodes = mutations.flatMap((mutation) => Array.from(mutation.addedNodes));
|
||||
|
||||
for (const descriptor of descriptors) {
|
||||
for (const node of addedNodes) {
|
||||
if (node instanceof HTMLElement && node.hasAttribute(`data-${descriptor.name}`)) {
|
||||
handleNewElement(node, descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} element
|
||||
* @param {AnnotationDescriptor} descriptor
|
||||
*/
|
||||
function handleNewElement(element, descriptor) {
|
||||
const cleanup = descriptor.onAdd(element);
|
||||
|
||||
if (cleanup) {
|
||||
cleanupFunctions.set(element, cleanup);
|
||||
}
|
||||
}
|
82
.keycloakify/login/js/webauthnAuthenticate.js
Normal file
@ -0,0 +1,82 @@
|
||||
import { base64url } from "rfc4648";
|
||||
|
||||
export async function authenticateByWebAuthn(input) {
|
||||
if (!input.isUserIdentified) {
|
||||
try {
|
||||
const result = await doAuthenticate([], input.challenge, input.userVerification, input.rpId, input.createTimeout, input.errmsg);
|
||||
returnSuccess(result);
|
||||
} catch (error) {
|
||||
returnFailure(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
checkAllowCredentials(input.challenge, input.userVerification, input.rpId, input.createTimeout, input.errmsg);
|
||||
}
|
||||
|
||||
async function checkAllowCredentials(challenge, userVerification, rpId, createTimeout, errmsg) {
|
||||
const allowCredentials = [];
|
||||
const authnUse = document.forms['authn_select'].authn_use_chk;
|
||||
if (authnUse !== undefined) {
|
||||
if (authnUse.length === undefined) {
|
||||
allowCredentials.push({
|
||||
id: base64url.parse(authnUse.value, {loose: true}),
|
||||
type: 'public-key',
|
||||
});
|
||||
} else {
|
||||
authnUse.forEach((entry) =>
|
||||
allowCredentials.push({
|
||||
id: base64url.parse(entry.value, {loose: true}),
|
||||
type: 'public-key',
|
||||
}));
|
||||
}
|
||||
}
|
||||
try {
|
||||
const result = await doAuthenticate(allowCredentials, challenge, userVerification, rpId, createTimeout, errmsg);
|
||||
returnSuccess(result);
|
||||
} catch (error) {
|
||||
returnFailure(error);
|
||||
}
|
||||
}
|
||||
|
||||
function doAuthenticate(allowCredentials, challenge, userVerification, rpId, createTimeout, errmsg) {
|
||||
// Check if WebAuthn is supported by this browser
|
||||
if (!window.PublicKeyCredential) {
|
||||
returnFailure(errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
const publicKey = {
|
||||
rpId : rpId,
|
||||
challenge: base64url.parse(challenge, { loose: true })
|
||||
};
|
||||
|
||||
if (createTimeout !== 0) {
|
||||
publicKey.timeout = createTimeout * 1000;
|
||||
}
|
||||
|
||||
if (allowCredentials.length) {
|
||||
publicKey.allowCredentials = allowCredentials;
|
||||
}
|
||||
|
||||
if (userVerification !== 'not specified') {
|
||||
publicKey.userVerification = userVerification;
|
||||
}
|
||||
|
||||
return navigator.credentials.get({publicKey});
|
||||
}
|
||||
|
||||
export function returnSuccess(result) {
|
||||
document.getElementById("clientDataJSON").value = base64url.stringify(new Uint8Array(result.response.clientDataJSON), { pad: false });
|
||||
document.getElementById("authenticatorData").value = base64url.stringify(new Uint8Array(result.response.authenticatorData), { pad: false });
|
||||
document.getElementById("signature").value = base64url.stringify(new Uint8Array(result.response.signature), { pad: false });
|
||||
document.getElementById("credentialId").value = result.id;
|
||||
if (result.response.userHandle) {
|
||||
document.getElementById("userHandle").value = base64url.stringify(new Uint8Array(result.response.userHandle), { pad: false });
|
||||
}
|
||||
document.getElementById("webauth").submit();
|
||||
}
|
||||
|
||||
export function returnFailure(err) {
|
||||
document.getElementById("error").value = err;
|
||||
document.getElementById("webauth").submit();
|
||||
}
|
140
.keycloakify/login/js/webauthnRegister.js
Normal file
@ -0,0 +1,140 @@
|
||||
import { base64url } from "rfc4648";
|
||||
|
||||
export async function registerByWebAuthn(input) {
|
||||
|
||||
// Check if WebAuthn is supported by this browser
|
||||
if (!window.PublicKeyCredential) {
|
||||
returnFailure(input.errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
const publicKey = {
|
||||
challenge: base64url.parse(input.challenge, {loose: true}),
|
||||
rp: {id: input.rpId, name: input.rpEntityName},
|
||||
user: {
|
||||
id: base64url.parse(input.userid, {loose: true}),
|
||||
name: input.username,
|
||||
displayName: input.username
|
||||
},
|
||||
pubKeyCredParams: getPubKeyCredParams(input.signatureAlgorithms),
|
||||
};
|
||||
|
||||
if (input.attestationConveyancePreference !== 'not specified') {
|
||||
publicKey.attestation = input.attestationConveyancePreference;
|
||||
}
|
||||
|
||||
const authenticatorSelection = {};
|
||||
let isAuthenticatorSelectionSpecified = false;
|
||||
|
||||
if (input.authenticatorAttachment !== 'not specified') {
|
||||
authenticatorSelection.authenticatorAttachment = input.authenticatorAttachment;
|
||||
isAuthenticatorSelectionSpecified = true;
|
||||
}
|
||||
|
||||
if (input.requireResidentKey !== 'not specified') {
|
||||
if (input.requireResidentKey === 'Yes') {
|
||||
authenticatorSelection.requireResidentKey = true;
|
||||
} else {
|
||||
authenticatorSelection.requireResidentKey = false;
|
||||
}
|
||||
isAuthenticatorSelectionSpecified = true;
|
||||
}
|
||||
|
||||
if (input.userVerificationRequirement !== 'not specified') {
|
||||
authenticatorSelection.userVerification = input.userVerificationRequirement;
|
||||
isAuthenticatorSelectionSpecified = true;
|
||||
}
|
||||
|
||||
if (isAuthenticatorSelectionSpecified) {
|
||||
publicKey.authenticatorSelection = authenticatorSelection;
|
||||
}
|
||||
|
||||
if (input.createTimeout !== 0) {
|
||||
publicKey.timeout = input.createTimeout * 1000;
|
||||
}
|
||||
|
||||
const excludeCredentials = getExcludeCredentials(input.excludeCredentialIds);
|
||||
if (excludeCredentials.length > 0) {
|
||||
publicKey.excludeCredentials = excludeCredentials;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await doRegister(publicKey);
|
||||
returnSuccess(result, input.initLabel, input.initLabelPrompt);
|
||||
} catch (error) {
|
||||
returnFailure(error);
|
||||
}
|
||||
}
|
||||
|
||||
function doRegister(publicKey) {
|
||||
return navigator.credentials.create({publicKey});
|
||||
}
|
||||
|
||||
function getPubKeyCredParams(signatureAlgorithmsList) {
|
||||
const pubKeyCredParams = [];
|
||||
if (signatureAlgorithmsList.length === 0) {
|
||||
pubKeyCredParams.push({type: "public-key", alg: -7});
|
||||
return pubKeyCredParams;
|
||||
}
|
||||
|
||||
for (const entry of signatureAlgorithmsList) {
|
||||
pubKeyCredParams.push({
|
||||
type: "public-key",
|
||||
alg: entry
|
||||
});
|
||||
}
|
||||
|
||||
return pubKeyCredParams;
|
||||
}
|
||||
|
||||
function getExcludeCredentials(excludeCredentialIds) {
|
||||
const excludeCredentials = [];
|
||||
if (excludeCredentialIds === "") {
|
||||
return excludeCredentials;
|
||||
}
|
||||
|
||||
for (const entry of excludeCredentialIds.split(',')) {
|
||||
excludeCredentials.push({
|
||||
type: "public-key",
|
||||
id: base64url.parse(entry, {loose: true})
|
||||
});
|
||||
}
|
||||
|
||||
return excludeCredentials;
|
||||
}
|
||||
|
||||
function getTransportsAsString(transportsList) {
|
||||
if (!Array.isArray(transportsList)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return transportsList.join();
|
||||
}
|
||||
|
||||
function returnSuccess(result, initLabel, initLabelPrompt) {
|
||||
document.getElementById("clientDataJSON").value = base64url.stringify(new Uint8Array(result.response.clientDataJSON), {pad: false});
|
||||
document.getElementById("attestationObject").value = base64url.stringify(new Uint8Array(result.response.attestationObject), {pad: false});
|
||||
document.getElementById("publicKeyCredentialId").value = base64url.stringify(new Uint8Array(result.rawId), {pad: false});
|
||||
|
||||
if (typeof result.response.getTransports === "function") {
|
||||
const transports = result.response.getTransports();
|
||||
if (transports) {
|
||||
document.getElementById("transports").value = getTransportsAsString(transports);
|
||||
}
|
||||
} else {
|
||||
console.log("Your browser is not able to recognize supported transport media for the authenticator.");
|
||||
}
|
||||
|
||||
let labelResult = window.prompt(initLabelPrompt, initLabel);
|
||||
if (labelResult === null) {
|
||||
labelResult = initLabel;
|
||||
}
|
||||
document.getElementById("authenticatorLabel").value = labelResult;
|
||||
|
||||
document.getElementById("register").submit();
|
||||
}
|
||||
|
||||
function returnFailure(err) {
|
||||
document.getElementById("error").value = err;
|
||||
document.getElementById("register").submit();
|
||||
}
|
BIN
.keycloakify/login/resources-common/img/favicon.ico
Normal file
After Width: | Height: | Size: 627 B |
22
.keycloakify/login/resources-common/lib/pficon/pficon.css
Normal file
@ -0,0 +1,22 @@
|
||||
/*!
|
||||
* This folder contains updated PatternFly4 icons (version 2020.13).
|
||||
* After the PF4 transition is finished this folder will be deleted.
|
||||
*/
|
||||
|
||||
@font-face {
|
||||
font-family: "pficon-tmp";
|
||||
src: url("./pficon.woff2") format("woff2");
|
||||
}
|
||||
|
||||
.pf-icon-openshift:before {
|
||||
font-family: "pficon-tmp";
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
text-transform: none; }
|
||||
|
||||
.pf-icon-openshift:before {
|
||||
content: ""; }
|
BIN
.keycloakify/login/resources-common/lib/pficon/pficon.woff2
Normal file
2
.keycloakify/login/resources-common/node_modules/@patternfly/patternfly/patternfly.min.css
generated
vendored
Normal file
2
.keycloakify/login/resources-common/node_modules/jquery/dist/jquery.min.js
generated
vendored
Normal file
5
.keycloakify/login/resources-common/node_modules/patternfly/dist/css/patternfly-additions.min.css
generated
vendored
Normal file
8
.keycloakify/login/resources-common/node_modules/patternfly/dist/css/patternfly.min.css
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.ttf
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Light-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Regular-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Semibold-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.ttf
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.woff
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/fontawesome-webfont.woff2
generated
vendored
Normal file
BIN
.keycloakify/login/resources-common/node_modules/patternfly/dist/img/bg-login.jpg
generated
vendored
Normal file
After Width: | Height: | Size: 46 KiB |
178
.keycloakify/login/resources-common/node_modules/rfc4648/lib/rfc4648.js
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
function parse(string, encoding, opts) {
|
||||
var _opts$out;
|
||||
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
// Build the character lookup table:
|
||||
if (!encoding.codes) {
|
||||
encoding.codes = {};
|
||||
|
||||
for (var i = 0; i < encoding.chars.length; ++i) {
|
||||
encoding.codes[encoding.chars[i]] = i;
|
||||
}
|
||||
} // The string must have a whole number of bytes:
|
||||
|
||||
|
||||
if (!opts.loose && string.length * encoding.bits & 7) {
|
||||
throw new SyntaxError('Invalid padding');
|
||||
} // Count the padding bytes:
|
||||
|
||||
|
||||
var end = string.length;
|
||||
|
||||
while (string[end - 1] === '=') {
|
||||
--end; // If we get a whole number of bytes, there is too much padding:
|
||||
|
||||
if (!opts.loose && !((string.length - end) * encoding.bits & 7)) {
|
||||
throw new SyntaxError('Invalid padding');
|
||||
}
|
||||
} // Allocate the output:
|
||||
|
||||
|
||||
var out = new ((_opts$out = opts.out) != null ? _opts$out : Uint8Array)(end * encoding.bits / 8 | 0); // Parse the data:
|
||||
|
||||
var bits = 0; // Number of bits currently in the buffer
|
||||
|
||||
var buffer = 0; // Bits waiting to be written out, MSB first
|
||||
|
||||
var written = 0; // Next byte to write
|
||||
|
||||
for (var _i = 0; _i < end; ++_i) {
|
||||
// Read one character from the string:
|
||||
var value = encoding.codes[string[_i]];
|
||||
|
||||
if (value === undefined) {
|
||||
throw new SyntaxError('Invalid character ' + string[_i]);
|
||||
} // Append the bits to the buffer:
|
||||
|
||||
|
||||
buffer = buffer << encoding.bits | value;
|
||||
bits += encoding.bits; // Write out some bits if the buffer has a byte's worth:
|
||||
|
||||
if (bits >= 8) {
|
||||
bits -= 8;
|
||||
out[written++] = 0xff & buffer >> bits;
|
||||
}
|
||||
} // Verify that we have received just enough bits:
|
||||
|
||||
|
||||
if (bits >= encoding.bits || 0xff & buffer << 8 - bits) {
|
||||
throw new SyntaxError('Unexpected end of data');
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
function stringify(data, encoding, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
var _opts = opts,
|
||||
_opts$pad = _opts.pad,
|
||||
pad = _opts$pad === void 0 ? true : _opts$pad;
|
||||
var mask = (1 << encoding.bits) - 1;
|
||||
var out = '';
|
||||
var bits = 0; // Number of bits currently in the buffer
|
||||
|
||||
var buffer = 0; // Bits waiting to be written out, MSB first
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
// Slurp data into the buffer:
|
||||
buffer = buffer << 8 | 0xff & data[i];
|
||||
bits += 8; // Write out as much as we can:
|
||||
|
||||
while (bits > encoding.bits) {
|
||||
bits -= encoding.bits;
|
||||
out += encoding.chars[mask & buffer >> bits];
|
||||
}
|
||||
} // Partial character:
|
||||
|
||||
|
||||
if (bits) {
|
||||
out += encoding.chars[mask & buffer << encoding.bits - bits];
|
||||
} // Add padding characters until we hit a byte boundary:
|
||||
|
||||
|
||||
if (pad) {
|
||||
while (out.length * encoding.bits & 7) {
|
||||
out += '=';
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
var base16Encoding = {
|
||||
chars: '0123456789ABCDEF',
|
||||
bits: 4
|
||||
};
|
||||
var base32Encoding = {
|
||||
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
|
||||
bits: 5
|
||||
};
|
||||
var base32HexEncoding = {
|
||||
chars: '0123456789ABCDEFGHIJKLMNOPQRSTUV',
|
||||
bits: 5
|
||||
};
|
||||
var base64Encoding = {
|
||||
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
||||
bits: 6
|
||||
};
|
||||
var base64UrlEncoding = {
|
||||
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
|
||||
bits: 6
|
||||
};
|
||||
var base16 = {
|
||||
parse: function parse$1(string, opts) {
|
||||
return parse(string.toUpperCase(), base16Encoding, opts);
|
||||
},
|
||||
stringify: function stringify$1(data, opts) {
|
||||
return stringify(data, base16Encoding, opts);
|
||||
}
|
||||
};
|
||||
var base32 = {
|
||||
parse: function parse$1(string, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
return parse(opts.loose ? string.toUpperCase().replace(/0/g, 'O').replace(/1/g, 'L').replace(/8/g, 'B') : string, base32Encoding, opts);
|
||||
},
|
||||
stringify: function stringify$1(data, opts) {
|
||||
return stringify(data, base32Encoding, opts);
|
||||
}
|
||||
};
|
||||
var base32hex = {
|
||||
parse: function parse$1(string, opts) {
|
||||
return parse(string, base32HexEncoding, opts);
|
||||
},
|
||||
stringify: function stringify$1(data, opts) {
|
||||
return stringify(data, base32HexEncoding, opts);
|
||||
}
|
||||
};
|
||||
var base64 = {
|
||||
parse: function parse$1(string, opts) {
|
||||
return parse(string, base64Encoding, opts);
|
||||
},
|
||||
stringify: function stringify$1(data, opts) {
|
||||
return stringify(data, base64Encoding, opts);
|
||||
}
|
||||
};
|
||||
var base64url = {
|
||||
parse: function parse$1(string, opts) {
|
||||
return parse(string, base64UrlEncoding, opts);
|
||||
},
|
||||
stringify: function stringify$1(data, opts) {
|
||||
return stringify(data, base64UrlEncoding, opts);
|
||||
}
|
||||
};
|
||||
var codec = {
|
||||
parse: parse,
|
||||
stringify: stringify
|
||||
};
|
||||
|
||||
export { base16, base32, base32hex, base64, base64url, codec };
|
@ -1 +1 @@
|
||||
{"generatedAt":1725957919917,"builder":{"name":"webpack5"},"hasCustomBabel":false,"hasCustomWebpack":false,"hasStaticDirs":true,"hasStorybookEslint":true,"refCount":0,"packageManager":{"type":"yarn","version":"1.22.22"},"storybookVersion":"6.5.16","language":"typescript","storybookPackages":{"@storybook/builder-webpack5":{"version":"6.5.16"},"@storybook/manager-webpack5":{"version":"6.5.16"},"@storybook/react":{"version":"6.5.16"},"eslint-plugin-storybook":{"version":"0.6.11"}},"framework":{"name":"react"},"addons":{"storybook-dark-mode":{"version":"1.1.2"},"@storybook/addon-a11y":{"version":"6.5.16"}}}
|
||||
{"generatedAt":1725987895328,"builder":{"name":"webpack5"},"hasCustomBabel":false,"hasCustomWebpack":false,"hasStaticDirs":true,"hasStorybookEslint":true,"refCount":0,"packageManager":{"type":"yarn","version":"1.22.22"},"storybookVersion":"6.5.16","language":"typescript","storybookPackages":{"@storybook/builder-webpack5":{"version":"6.5.16"},"@storybook/manager-webpack5":{"version":"6.5.16"},"@storybook/react":{"version":"6.5.16"},"eslint-plugin-storybook":{"version":"0.6.11"}},"framework":{"name":"react"},"addons":{"storybook-dark-mode":{"version":"1.1.2"},"@storybook/addon-a11y":{"version":"6.5.16"}}}
|
||||
|