diff --git a/.gitguardian.yaml b/.gitguardian.yaml new file mode 100644 index 0000000..309e932 --- /dev/null +++ b/.gitguardian.yaml @@ -0,0 +1,5 @@ +version: 2 +secret: + ignore: + - name: + match: "kcFormPasswordVisibilityButtonClass=pf-v5-c-button pf-m-plain" diff --git a/.gitignore b/.gitignore index 11138ad..bef3927 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ ol-keycloak/ol-spi/target/* ol-keycloak/oltheme/target/* .DS_Store plugins/ +node_modules/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..46661fa --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,19 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "f12edd9c7be1c20cfa42420fd0e6df71e42b51ea" + hooks: + - id: prettier + - repo: https://github.com/Yelp/detect-secrets + rev: v1.4.0 + hooks: + - id: detect-secrets + args: ["--baseline", ".secrets.baseline"] diff --git a/.prettierrc.mjs b/.prettierrc.mjs new file mode 100644 index 0000000..2e57b15 --- /dev/null +++ b/.prettierrc.mjs @@ -0,0 +1,15 @@ +// prettier.config.js, .prettierrc.js, prettier.config.mjs, or .prettierrc.mjs + +/** @type {import("prettier").Config} */ +const config = { + overrides: [ + { + files: ["*.ftl"], + options: { + parser: "html", + }, + }, + ], +}; + +export default config; diff --git a/.secrets.baseline b/.secrets.baseline new file mode 100644 index 0000000..cbe3b84 --- /dev/null +++ b/.secrets.baseline @@ -0,0 +1,126 @@ +{ + "version": "1.4.0", + "plugins_used": [ + { + "name": "ArtifactoryDetector" + }, + { + "name": "AWSKeyDetector" + }, + { + "name": "AzureStorageKeyDetector" + }, + { + "name": "Base64HighEntropyString", + "limit": 4.5 + }, + { + "name": "BasicAuthDetector" + }, + { + "name": "CloudantDetector" + }, + { + "name": "DiscordBotTokenDetector" + }, + { + "name": "GitHubTokenDetector" + }, + { + "name": "HexHighEntropyString", + "limit": 3.0 + }, + { + "name": "IbmCloudIamDetector" + }, + { + "name": "IbmCosHmacDetector" + }, + { + "name": "JwtTokenDetector" + }, + { + "name": "KeywordDetector", + "keyword_exclude": "" + }, + { + "name": "MailchimpDetector" + }, + { + "name": "NpmDetector" + }, + { + "name": "PrivateKeyDetector" + }, + { + "name": "SendGridDetector" + }, + { + "name": "SlackDetector" + }, + { + "name": "SoftlayerDetector" + }, + { + "name": "SquareOAuthDetector" + }, + { + "name": "StripeDetector" + }, + { + "name": "TwilioKeyDetector" + } + ], + "filters_used": [ + { + "path": "detect_secrets.filters.allowlist.is_line_allowlisted" + }, + { + "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", + "min_level": 2 + }, + { + "path": "detect_secrets.filters.gibberish.should_exclude_secret", + "limit": 3.7 + }, + { + "path": "detect_secrets.filters.heuristic.is_indirect_reference" + }, + { + "path": "detect_secrets.filters.heuristic.is_likely_id_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_lock_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_potential_uuid" + }, + { + "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" + }, + { + "path": "detect_secrets.filters.heuristic.is_sequential_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_swagger_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_templated_secret" + } + ], + "results": { + ".pre-commit-config.yaml": [ + { + "type": "Hex High Entropy String", + "filename": ".pre-commit-config.yaml", + "hashed_secret": "93b6a9c0402c7516c5c416ae0bbce27bd2ef9e97", + "is_verified": false, + "line_number": 12 + } + ] + }, + "generated_at": "2024-03-20T21:23:15Z" +} diff --git a/ol-keycloak/ol-spi/src/main/java/forms/login/freemarker/OlFreeMarkerLoginFormsProvider.java b/ol-keycloak/ol-spi/src/main/java/forms/login/freemarker/OlFreeMarkerLoginFormsProvider.java index 131c7da..d28bd2f 100644 --- a/ol-keycloak/ol-spi/src/main/java/forms/login/freemarker/OlFreeMarkerLoginFormsProvider.java +++ b/ol-keycloak/ol-spi/src/main/java/forms/login/freemarker/OlFreeMarkerLoginFormsProvider.java @@ -36,16 +36,19 @@ public OlFreeMarkerLoginFormsProvider(KeycloakSession session) { protected void createCommonAttributes(Theme theme, Locale locale, Properties messagesBundle, UriBuilder baseUriBuilder, LoginFormsPages page) { super.createCommonAttributes(theme, locale, messagesBundle,baseUriBuilder,page); if (page == LOGIN) { - String firstName = ""; + String attemptedName = ""; Boolean hasCredentials = false; UserModel user = context.getUser(); - if (context.getUser() != null) { - firstName = user.getFirstName(); + if (user != null) { + if (user.getFirstName() != null && user.getLastName() != null) { + attemptedName = user.getFirstName().concat(" ").concat(user.getLastName()); + } + Stream credentials = user.credentialManager().getStoredCredentialsStream(); hasCredentials = credentials.count() > 0; - + } - this.attributes.put("firstName", firstName); + this.attributes.put("attemptedName", attemptedName); this.attributes.put("hasCredentials", hasCredentials); } } diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/header.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/header.ftl new file mode 100644 index 0000000..56a197c --- /dev/null +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/header.ftl @@ -0,0 +1,8 @@ + + + + + Open + diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-password.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-password.ftl index ee7d94b..2740e0c 100755 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-password.ftl +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-password.ftl @@ -10,14 +10,16 @@
- - +
+ + +
<#if messagesPerField.existsError('password')> diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-username.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-username.ftl index b02186d..a50199f 100755 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-username.ftl +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-username.ftl @@ -7,7 +7,7 @@
<#if realm.password>
+ method="post" class="${properties.kcFormClass}"> <#if !usernameHidden??>
- + <#elseif section = "socialProviders" > +
+ or +
+ <#include "social-providers.ftl"> <#elseif section = "info" > <#if realm.password && realm.registrationAllowed && !registrationDisabled??>
diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-verify-email.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-verify-email.ftl index f79ffee..c47097f 100755 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-verify-email.ftl +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login-verify-email.ftl @@ -1,36 +1,21 @@ <#import "template.ftl" as layout> -<@layout.registrationLayout displayInfo=true; section> +<@layout.registrationLayout displayInfo=true displayMessage=false; section> <#if section = "header"> ${msg("emailVerifyTitle")} <#elseif section = "form"> -

${msg("emailVerifyInstruction1",user.email)}

- <#elseif section = "info">

- ${msg("emailVerifyInstruction2")} -
-

+ ${msg("emailVerifyInstruction1")} +
+ ${user.email} +

+ <#elseif section = "info"> +

${msg("emailVerifyInstruction2")}

+
+

${msg("emailVerifyInstruction3")}

+

+ ${msg("emailVerifyInstruction4Bold")} + ${msg("emailVerifyInstruction4")} + ${msg("emailVerifySupportLinkTitle")}.

-
-
- ${msg("emailVerifyInstructionOL1")} -
-
- ${msg("emailVerifyInstructionOL2Bold")} ${msg("emailVerifyInstructionOL2")} -
-
- ${msg("emailVerifyInstructionOL3Bold")} ${msg("emailVerifyInstructionOL3")} -
-
- ${msg("emailVerifyInstructionOL4Bold")} ${msg("emailVerifyInstructionOL4")} -
-
-
- ${msg("emailVerifyInstructionOL5Bold")} ${msg("emailVerifyInstructionOL5")} -
- ${msg("emailVerifySupportLinkTitleOL")} -
-
diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login.ftl index 02e1b74..c9fa23d 100644 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login.ftl +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/login.ftl @@ -1,93 +1,123 @@ <#import "template.ftl" as layout> <@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','password') displayInfo=realm.password && realm.registrationAllowed && !registrationDisabled??; section> <#if section = "header"> - ${msg("loginAccountTitle")} + <#if attemptedName??> + ${msg("loginGreeting")} ${attemptedName}! + <#else> + ${msg("loginAccountTitle")} + <#elseif section = "form">
-
- <#if realm.password && !social.providers??> - <#if hasCredentials> - - <#if !usernameHidden??> -
- +
+ <#if realm.password && !social.providers??> + <#if hasCredentials> + + <#if !usernameHidden??> +
+ - + - <#if messagesPerField.existsError('username','password')> - - ${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc} + + + + + -
- - -
- - -
- -
- - <#if usernameHidden?? && messagesPerField.existsError('username','password')> + <#if messagesPerField.existsError('username','password')> ${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
+ + +
+ + +
+ +
+ +
+
+ + <#if usernameHidden?? && messagesPerField.existsError('username','password')> + + ${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc} + + -
-
- <#if realm.rememberMe && !usernameHidden??> -
- -
+
+ +
+
+ <#if realm.rememberMe && !usernameHidden??> +
+ +
+ +
+
+ <#if realm.resetPasswordAllowed> + ${msg("doForgotPassword")} -
-
- <#if realm.resetPasswordAllowed> - ${msg("doForgotPassword")} - -
+
-
+
-
- value="${auth.selectedCredential}"/> - -
- - <#elseif realm.resetPasswordAllowed> -
-
-

- Password required. - For security reasons you will need to create a new password for your account. -

-
-
- -
-
- <#else> +
+ value="${auth.selectedCredential}"/> + +
+ + <#elseif realm.resetPasswordAllowed> +
-

Unable to log you in - no password and password reset is disabled by the administrator.

+

+ Password required. + For security reasons you will need to create a new password for your account. +

- +
+ +
+
+ <#else> +
+

Unable to log you in - no password and password reset is disabled by the administrator.

+
+
@@ -103,25 +133,9 @@ <#elseif section = "socialProviders" > <#if realm.password && social.providers??> -
-

${msg("ol-linked-identity-provider-label")}

- - -
+

You already have a login with:

+ <#include "social-providers.ftl"> + diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/messages/messages_en.properties b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/messages/messages_en.properties index 7d4b21c..7d32244 100644 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/messages/messages_en.properties +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/messages/messages_en.properties @@ -1,39 +1,43 @@ -noAccount=Not a member? +noAccount=Don''t have an account? doRegister=Sign up -loginAccountTitle=Login +doRegisterSubmit=Next +loginAccountTitle=Sign In loginGreeting=Hello, loginTitleHtml=Open Learning loginTitle=MIT Open registerTitle=Join MIT Open for free -registerLegalAgreementText=By creating an account you agree to the +registerInstruction=Enter your information to sign up +registerLegalAgreementText=By creating an account I agree to the registerTermsOfService=Terms of Service registerPrivacyPolicy=Privacy Policy ol-linked-identity-provider-label=You already have a login with doLogIn=Next doResetPasswordSubmit=Next resetPasswordSubtitle=Enter your email for a password reset link. -doForgotPassword=Forgot your password? +doForgotPassword=Forgot password? emailForgotTitle=Forgot your password? emailForgotSubtitle=Enter your email for a password reset link. -invalidPasswordMessage=Wrong password. Try again or reset password below -invalidUsernameOrEmailMessage=Couldn''t find your MIT Open account. +invalidPasswordMessage=The password you have entered is incorrect. Please try again or select Forgot Password below. +invalidUsernameOrEmailMessage= We do not have an account for that email on record. Please try another email or sign up for free. emailSentMessage=We''ve emailed your instructions for setting your password. You should receive them shortly. updatePasswordTitle=Create a new password -backToLogin=« Back to Login +backToLogin=« Back to Sign In alreadyHaveAnAccountRegister=Already have an account? -logInRegister=Login +logInRegister=Sign In loginSubtitle=Please enter your email address. loginUsernameSubtitle=Choose one of the options to log in forgotPasswordSendResetEmail=Send Reset Email -emailVerifyInstruction3=Re-send the email -emailVerifyInstructionOL1=If you do NOT receive your verification email, here''s what to do: -emailVerifyInstructionOL2Bold=Wait a few moments. -emailVerifyInstructionOL2=It might take several minutes to receive your verification email. -emailVerifyInstructionOL3Bold=Check your spam folder. -emailVerifyInstructionOL3=It might be there. -emailVerifyInstructionOL4Bold=Is your email correct? -emailVerifyInstructionOL4=If you made a typo, no problem, just try creating an account again. -emailVerifyInstructionOL5Bold=Still no verification email? -emailVerifyInstructionOL5=Please contact our MITx Online -emailVerifySupportLinkTitleOL=Customer Support Center +emailVerifyInstruction1=A verification email has been sent to: +emailVerifyInstruction2=Please click the link from your email to continue. +emailVerifyInstruction3=Check the email inbox you signed up with. You may need to check the Spam folder. +emailVerifyInstruction4Bold=Still no verification email? +emailVerifyInstruction4=Please contact our MIT Open +emailVerifyResend=Resend Email +emailVerifySupportLinkTitle=Customer Support Center createPassword=Create Password +passwordRequiredTitle=Password Required. +passwordRequiredText=For security reasons you will need to create a new password for your account. +passwordRequiredUnableText=Unable to log you in - you have no password and password reset is disabled by the administrator. + +usernameOrEmail=Email +and=and diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/register.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/register.ftl index 137299c..39ac1bc 100755 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/register.ftl +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/register.ftl @@ -4,6 +4,7 @@ <#if section = "header"> ${msg("registerTitle")} <#elseif section = "form"> +

${msg("registerInstruction")}

@@ -134,48 +135,33 @@
- - -
- -
- -
-
- ${msg('alreadyHaveAnAccountRegister')} ${kcSanitize(msg("logInRegister"))?no_esc} -
+
+ <#if section = "socialProviders" > - <#if realm.password && (social.providers?? || unlinkedProviders??)> -
or
- - <#if realm.password && social.providers??> -
- +
+ or +
+ <#include "social-providers.ftl"> + + <#if section = "footer"> +
+
+
+ ${msg('alreadyHaveAnAccountRegister')} ${kcSanitize(msg("logInRegister"))?no_esc} +
+
+ + - +
diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/resources/css/styles.css b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/resources/css/styles.css index b005d16..dba798a 100644 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/resources/css/styles.css +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/resources/css/styles.css @@ -1,489 +1,303 @@ +:where(:root) { + --Brand-Red: #a31f34; + --Brand-Blue: #03152d; + + --pf-v5-global--link--Color: var(--Brand-Red); + + --pf-v5-global--link--TextDecoration: underline; +} + +.pf-v5-c-alert { + border-radius: 3px; + border: 0; + background: #ffe8e9; + color: #750014; +} + +.pf-v5-c-login { + --pf-v5-c-login__main-body--PaddingBottom: 0; +} + +.pf-v5-c-form { + --pf-v5-c-form--GridGap: 0.3rem; +} + +.pf-v5-c-login__main-footer { + padding-inline-end: var(--pf-v5-c-login__main-body--PaddingRight); + padding-inline-start: var(--pf-v5-c-login__main-body--PaddingLeft); +} + +.pf-v5-c-form-control { + border-radius: 4px; + border: 1px solid #d5dae1; + background: var(--White, #fff); +} + +.pf-v5-c-form-control::after { + border-block-end: none; +} + +.pf-v5-c-button { + --pf-v5-c-button--m-primary--Color: #ffffff; + --pf-v5-c-button--m-primary--BackgroundColor: var(--Brand-Blue); + + --pf-v5-c-button--m-secondary--Color: #03152d; + --pf-v5-c-button--m-secondary--after--BorderColor: #d5dae1; + + --pf-v5-c-button--m-secondary--focus--Color: var(--Brand-Blue); + --pf-v5-c-button--m-secondary--focus--after--BorderColor: var(--Brand-Blue); + + --pf-v5-c-button--m-secondary--hover--Color: var(--Brand-Blue); + --pf-v5-c-button--m-secondary--hover--after--BorderColor: var(--Brand-Blue); +} + +.pf-v5-c-button:hover { + cursor: pointer; +} + +a.pf-v5-c-button, +a.pf-v5-c-button:hover, +a.pf-v5-c-button:active, +a.pf-v5-c-button:focus, +a.pf-v5-c-button:visited { + text-decoration: none; + text-decoration-line: none; +} + .login-pf { - background: var(--GreyLite, #F0F5F7); + background: #ffffff; + font-family: Inter; + max-width: 477px; + margin: auto; } .login-pf body { - background: var(--GreyLite, #F0F5F7); + background: #ffffff; } -.alert-error { - border-radius: 3px; - border: 1px solid rgba(194, 111, 111, 0.50); - background: #FCE6E6; +@media (max-width: 768px) { + .login-pf { + margin: 0px 10px 0px 10px; + } } -#kc-page-title { - margin-top: 0px; - margin-bottom: 0px; -} -.login-pf-page { - max-width: 477px; - margin: auto; - - @media (max-width: 768px) { - margin: 0px 10px 0px 10px; - } - - #kc-header { - margin-top: 70px; - margin-bottom: 25px; - } - .card-pf { - display: flex; - margin: auto; - padding: 40px; - flex-direction: column; - align-items: flex-start; - border-radius: 3px; - border-top: 2px solid var(--BrandBlue, #03152D); - background: var(--White, #FFF); - - /* Shadow-1 */ - box-shadow: 0px 2px 2px 0px rgba(3, 21, 45, 0.05); - - #kc-content { - align-self: stretch; - - .pf-m-error { - color: var(--BrandRed, #A31F34); - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: normal; - letter-spacing: -0.1px; - display: inline-block; - margin-top: 10px; - } - - #kc-reset-password-form { - .form-group { - margin-bottom: 20px; - } - } - - #kc-passwd-update-form { - display: flex; - gap: 20px; - flex-direction: column; - } - - #kc-register-form { - .form-group { - margin-bottom: 20px; - } - - #kc-form-legal-options { - margin-bottom: 20px; - } - - #kc-form-options { - display: flex; - justify-content: center; - align-items: center; - gap: 5px; - margin-top: 30px; - } - } - - #reset-password-subtitle { - margin-bottom: 30px; - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Subheading */ - font-family: Inter; - font-size: 16px; - font-style: normal; - font-weight: 400; - line-height: 140%; /* 22.4px */ - letter-spacing: -0.1px; - } - - .pf-c-form-control { - display: flex; - padding: 16px 16px; - flex-direction: column; - align-items: flex-start; - gap: 20px; - align-self: stretch; - border-radius: 4px; - border: 1px solid var(--BorderColor, #D5DAE1); - background: var(--White, #FFF); - height: 56px; - } - - #kc-content-wrapper { - - .textline{ - display: flex; - align-items: center; - justify-content: center; - color: var(--BrandBlue, #03152D); - margin-bottom: 25px; - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: normal; - letter-spacing: -0.1px; - } - .textline:before { - content: ""; - width: 150px; - height: 1px; - background: #D5DAE1; - margin: 0; - margin-right: 10px; - } - .textline:after { - content: ""; - width: 150px; - height: 1px; - background: #D5DAE1; - margin: 0; - margin-left: 10px; - } - - h2 { - margin-top: 0px; - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Subheading */ - font-family: Inter; - font-size: 16px; - font-style: normal; - font-weight: 400; - line-height: 140%; /* 22.4px */ - letter-spacing: -0.1px; - } - } - } - } - - .login-pf-header { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 15px; - align-self: stretch; - - #kc-username { - #kc-attempted-username { - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Heading */ - font-family: Inter; - font-size: 22px; - font-style: normal; - font-weight: 700; - line-height: normal; - letter-spacing: -0.1px; - } - } - } - - #kc-page-title { - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Heading */ - font-family: Inter; - font-size: 22px; - font-style: normal; - font-weight: 700; - line-height: normal; - letter-spacing: -0.1px; - } - - #title-subtitle { - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Subheading */ - font-family: Inter; - font-size: 16px; - font-style: normal; - font-weight: 400; - line-height: 140%; /* 22.4px */ - letter-spacing: -0.1px; - } - - #username { - display: flex; - padding: 16px 16px; - flex-direction: column; - align-items: flex-start; - gap: 10px; - align-self: stretch; - border-radius: 4px; - border: 1px solid var(--BorderColor, #D5DAE1); - background: var(--White, #FFF); - height: 56px; - } - - #kc-login { - margin-top: 20px; - } +.login-pf #kc-header { + margin-top: 70px; + margin-bottom: 25px; +} + +.login-pf a.logo-link, +.login-pf a.logo-link:hover, +.login-pf a.logo-link:visited, +.login-pf a.logo-link:active { + text-decoration: none; + underline: none; + color: #000; +} + +.login-pf a.logo-link svg { + height: 50px; +} + +.login-pf .pf-v5-c-login__main-header { + display: block; /* undo display: grid */ } + +.login-pf .login-pf-header { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 15px; + align-self: stretch; +} + +#kc-attempted-username { + color: #d5dae1; + leading-trim: both; + text-edge: cap; + + /* Heading */ + font-family: Inter; + font-size: 22px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: -0.1px; +} + +.login-pf #kc-page-title { + color: var(--Brand-Blue); + leading-trim: both; + text-edge: cap; + + /* Heading */ + font-family: Inter; + font-size: 22px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: -0.1px; +} + +.login-pf #title-subtitle { + color: var(--Brand-Blue); + leading-trim: both; + text-edge: cap; + + /* Subheading */ + font-family: Inter; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 140%; /* 22.4px */ + letter-spacing: -0.1px; +} + +.login-pf #kc-login { + margin-top: 20px; +} + .login-pf-page .login-pf-signup a { - margin-left: 0px; + margin-left: 0px; } .form-group { - margin-bottom: 0; + margin-bottom: 0; } #forgot-password-option { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 20px; - align-self: stretch; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 20px; + align-self: stretch; } #kc-page-title { - font-size: 38px; - font-weight: 700; + font-size: 38px; + font-weight: 700; } -.pf-c-form__label-text { - font-weight: normal !important; - font-size: 16px; +.pf-v5-c-form__label-text { + font-weight: normal !important; + font-size: 16px; } #kc-header { - display: flex; - align-items: center; + display: flex; + align-items: center; } #kc-header-wrapper { - align-self: baseline; - margin: auto; + align-self: baseline; + margin: auto; } .col-md-10 { - width: 100%; + width: 100%; } .login-pf-page .login-pf-signup { - gap: 5px; - margin: 20px 0 0; - - .instruction { - #kc-form-buttons { - margin-bottom: 10px; - } - } - - #ol-email-verify-instructions { - display: flex; - gap: 20px; - align-items: start; - flex-direction: column; - text-align: start; - margin-top: 30px; - - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Default */ - font-family: Inter; - font-size: 14px; - font-style: normal; - line-height: 20px; - letter-spacing: -0.1px; - - #email-verify-instruction-red { - color: var(--BrandRed, #A31F34); - leading-trim: both; - text-edge: cap; - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 700; - line-height: 20px; /* 142.857% */ - letter-spacing: -0.1px; - } - } - #ol-email-verify-instructions hr { - border: 0; - width: 100%; - background-color: #4d5258; - height: 1px; - margin: 0; - } + gap: 5px; + margin: 20px 0 0; } .login-pf-page .login-pf-signup span { - font-family: Inter; - font-size: 14px; - font-weight: 400; - line-height: 20px; - letter-spacing: -0.1px; - text-align: center; - color: #5F6368; + font-family: Inter; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: -0.1px; + text-align: center; + color: #5f6368; } /* footer styles START */ .footer { - display: inline-flex; - padding: 96px 10px 50px 10px; - justify-content: center; - align-items: center; - gap: 10px; - background: var(--GreyLite, #F0F5F7); - width: 100%; - flex-direction: row-reverse; - - @media (max-width: 768px) { - flex-wrap: wrap; - } - - #footer-links { - display: flex; - gap: 10px; - } - - span { - color: #000; - leading-trim: both; - text-edge: cap; - - /* Default */ - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 20px; /* 142.857% */ - letter-spacing: -0.1px; - } - - a { - display: flex; - justify-content: center; - align-items: center; - } + display: inline-flex; + padding: 96px 10px 50px 10px; + justify-content: center; + align-items: center; + gap: 10px; + width: 100%; + flex-direction: row-reverse; +} + +@media (max-width: 768px) { + .footer { + flex-wrap: wrap; + } +} + +.footer #footer-links { + display: flex; + gap: 10px; +} + +.footer span { + color: #000; + leading-trim: both; + text-edge: cap; + + /* Default */ + font-family: Inter; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.1px; } -/* footer styles END */ -a { - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 500; - line-height: normal; - letter-spacing: -0.1px; - text-decoration-line: underline; - transition: color 500ms; -} - -a:hover { - color: var(--BrandRed, #A31F34); -} - -.pf-c-button.pf-m-primary { - display: flex; - padding: 20px; - justify-content: center; - align-items: center; - align-self: stretch; - border-radius: 5px; - background: var(--BrandBlue, #03152D); - color: var(--White, #FFF); - leading-trim: both; - text-edge: cap; - font-family: Inter; - font-size: 16px; - font-style: normal; - font-weight: 600; - line-height: normal; - letter-spacing: 0.5px; - transition: background-color 500ms; -} - -.pf-c-button.pf-m-primary:hover { - background: var(--BrandRed, #A31F34); +.footer a { + display: flex; + justify-content: center; + align-items: center; } +/* footer styles END */ #input-error { - color: var(--BrandRed, #A31F34); - leading-trim: both; - text-edge: cap; - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: normal; - letter-spacing: -0.1px; - padding: 20px 0 20px 0; -} - -.kc-social-section { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 20px; - align-self: stretch; - - h4 { - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Default */ - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 20px; /* 142.857% */ - letter-spacing: -0.1px; - } -} -.kc-social-section h4 { - color: var(--BrandBlue, #03152D); - leading-trim: both; - text-edge: cap; - - /* Default */ - font-family: Inter; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 20px; /* 142.857% */ - letter-spacing: -0.1px; -} -.kc-social-item { - display: flex !important; - padding: 13px 20px; - justify-content: center; - align-items: center; - gap: 10px; - border-radius: 5px; - border: 1px solid var(--BorderColor, #D5DAE1); - background: var(--White, #FFF); - transition: background 500ms; - text-decoration-line: none; - --pf-c-button--after--BorderColor: transparent !important; -} -.kc-social-item:hover { - background: var(--GreyLite, #F0F5F7); -} -.kc-social-links { - width: 100%; -} - -.kc-social-links li { - width: inherit; + color: var(--Brand-Red); + leading-trim: both; + text-edge: cap; + font-family: Inter; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + letter-spacing: -0.1px; + padding: 20px 0 20px 0; +} + +.separator { + display: flex; + align-items: center; + text-align: center; +} + +.separator::before, +.separator::after { + content: ""; + flex: 1; + border-bottom: 1px solid #d5dae1; +} + +.separator:not(:empty)::before { + margin-right: 0.25em; +} + +.separator:not(:empty)::after { + margin-left: 0.25em; +} + +.g-recaptcha { + width: 100%; +} + +#password-input-group { + position: relative; +} + +.toggle-password-button { + position: absolute; + right: 1px; } diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/resources/img/favicon.ico b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/resources/img/favicon.ico new file mode 100644 index 0000000..595c3a3 Binary files /dev/null and b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/resources/img/favicon.ico differ diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/social-providers.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/social-providers.ftl new file mode 100644 index 0000000..b5a05c8 --- /dev/null +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/social-providers.ftl @@ -0,0 +1,85 @@ +<#if realm.password && social.providers??> + + diff --git a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/template.ftl b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/template.ftl index 88d450b..717c0af 100644 --- a/ol-keycloak/oltheme/src/main/resources/theme/ol/login/template.ftl +++ b/ol-keycloak/oltheme/src/main/resources/theme/ol/login/template.ftl @@ -1,6 +1,6 @@ <#macro registrationLayout bodyClass="" displayInfo=false displayMessage=true displayRequiredFields=false> - + lang="${locale.currentLanguageTag}"> @@ -12,7 +12,7 @@ - ${msg("loginTitle")} + ${msg("loginTitle",(realm.displayName!''))} <#if properties.stylesCommon?has_content> <#list properties.stylesCommon?split(' ') as style> @@ -34,176 +34,186 @@ + <#if authenticationSession??> + + + - -
-
- <#if auth?has_content && auth.showUsername()> - - - - -
- - - - - - - - - - - - - - + +