CodamAIDocs
Topicdone

The login pages (Keycloak theme)

Which pages the login theme provides and which flow leads to which page.

Variants
Sign inSign in in two stepsForgot passwordSet or change passwordOTPVerify email (Keycloak)Page expiredError and infoConfirm sign-outRegister (Keycloak)

What this is about

The CodamAI user interfaces have no login form of their own. When you sign in, you land on a page from Keycloak. How you get there is described in Sign in in the browser. This page is about the pages themselves: which ones exist, when they appear and where they lead.

A theme is the design of these pages. Keycloak builds every page from a template in the FreeMarker format (file extension .ftl) and fills it with texts from a language file. The CodamAI theme is called codamai and lives in the hub-login repository.

What a page looks like

Every page has two columns:

  • Left the actual form: heading, a short intro sentence, the fields, messages and buttons.
  • Right a product panel with a background image, the CodamAI modules and short value statements.

All texts are in messages_de.properties and messages_en.properties, including those of the product panel. A language picker appears at the top of the form as soon as internationalization is switched on in the realm and more than one language is offered.

The theme inherits from the stock keycloak theme (parent=keycloak). Pages it does not design itself, such as passkeys (WebAuthn), setting up a one-time code or “complete your profile”, therefore come with Keycloak’s standard layout, embedded in the CodamAI frame.

The page map

flowchart TD
    APP["User interface<br/>/login"] --> L["Sign in<br/>login.ftl"]
    L -- "password correct" --> OTP{"second factor<br/>set up?"}
    OTP -- yes --> O["One-time code<br/>login-otp.ftl"]
    OTP -- no --> PA{"required action<br/>open?"}
    O --> PA
    PA -- "set password" --> UP["New password<br/>login-update-password.ftl"]
    PA -- "verify email" --> VE["Verify email<br/>login-verify-email.ftl"]
    PA -- none --> BACK["back to the user interface<br/>with code"]
    UP --> BACK
    VE --> BACK
    L -- "link “Forgot password”" --> RP["Forgot password<br/>login-reset-password.ftl"]
    RP --> MAIL["Mail from Keycloak<br/>with link"]
    MAIL --> UP
    L -. "open too long" .-> EX["Page expired<br/>login-page-expired.ftl"]
    EX --> L

Read it like this: the sign-in always starts in the user interface, which forwards from /login to Keycloak on its own. After the password and, if needed, the one-time code, Keycloak checks whether a required action is still open for the account. A required action is a step Keycloak demands before the first access, for example “set password”. Only when nothing is open any more does Keycloak send the person back to the user interface with the one-time code.

Which page comes when

PageTemplateWhen it appearsWhere next
Sign inlogin.ftlon every sign-in without an existing Keycloak sessionone-time code, required action or back to the user interface
Username, then passwordlogin-username.ftl, login-password.ftlwhen the sign-in flow in the realm is switched to “username first”like “Sign in”
Forgot passwordlogin-reset-password.ftllink “Forgot password?” on the sign-in pageKeycloak sends a mail with a link
New passwordlogin-update-password.ftlrequired action UPDATE_PASSWORD, link from the CIAS welcome mail or from the “forgot password” mailback to the user interface
One-time code (OTP)login-otp.ftlthe account has a second factor set uprequired action or back
Verify emaillogin-verify-email.ftlrequired action VERIFY_EMAIL in Keycloakcontinues after the click in the mail
Page expiredlogin-page-expired.ftlthe sign-in page was open too long, or the browser went back“Restart” or “Continue”
Errorerror.ftlKeycloak cannot continue the process, for example with an invalid link“Back to application” if the client has a start address
Infoinfo.ftlafter a completed action, for example “account updated”continue link to the application or to the next action
Confirm sign-outlogout-confirm.ftlwhen signing out without an ID tokensigned out after the click
Registerregister.ftlonly if registration is switched on in the realmKeycloak creates the account

OTP means one-time password: a code from an authenticator app that is valid only once and only briefly.

What the realm settings show or hide

Some elements of the pages depend on switches in the realm. The theme checks them and shows the element only if the switch is on.

Switch in the realmshipped in cias-runtimeWhat happens on the sign-in page
resetPasswordAllowedonLink “Forgot password?” appears
registrationAllowedoffno link “Register”
rememberMeoffno checkbox “Remember me”
loginWithEmailAllowedonfield is labelled “Username or email”
internationalizationEnabledoffno language picker
verifyEmailoffKeycloak does not require its own email verification

The second column shows the realm file that cias-runtime ships under deploy/keycloak/import/. Another installation can set every switch differently.

The variants

What happens on the Keycloak pages

When: The user interface forwards from /login to Keycloak, and there is no session there yet.

  1. 1
    User→Keycloak
    enters username or email and password
  2. 2
    Keycloak
    Are the details correct?
  3. 3
    Keycloak
    otherwise: the same page with an error message below the fields
  4. 4
    Keycloak→Browser
    redirect back to the user interface with code

Result: The BFF of the user interface exchanges the code for tokens, see Sign in in the browser.

When: The sign-in flow in the realm asks for the username first.

Keycloak first shows login-username.ftl, then login-password.ftl. The second page shows the username at the top, plus a link to start over with a different name. The link “Forgot password?” is on the password page.

Result: Same result as the one-step sign-in.

When: Someone clicks “Forgot password?”. The link only appears if resetPasswordAllowed is on.

  1. 1
    User→Keycloak
    enters username or email
  2. 2
    Keycloak→Email
    sends a mail with a reset link
  3. 3
    User→Keycloak
    opens the link, sets a new password

Result: The mail comes from Keycloak, with its templates and the mail server setting in the realm, not through the CIAS mail templates.

When: The required action UPDATE_PASSWORD is open for the account, or someone opens a password link.

CIAS sets this required action when it activates an account from a registration, and adds a direct link to the welcome mail where possible. The page asks for the new password twice. The checkbox “Sign out from other devices” is preselected. If an application started the action itself, there is also “Cancel”.

Result: See Setting the password.

When: The account has a second factor, that is an authenticator app.

After the password, Keycloak asks for the code from the app. If several apps are set up, the person first picks which one to use. Setting up a second factor is a separate page that the theme takes over from the stock theme.

Result: Code correct → continue. Code wrong → the same page with an error message.

When: Keycloak itself requires a confirmation of the address (required action VERIFY_EMAIL, or verifyEmail in the realm).

The page says that a mail was sent to the address and offers a link to send it again. This page does not occur on the CIAS path: CIAS verifies the address itself, with its own link, and then marks it as verified in Keycloak.

Result: See Verify the email for the verification by CIAS.

When: The sign-in page was open too long, or the browser resubmitted an old page.

Two buttons: Restart starts the sign-in from the beginning, Continue tries to carry on at the current step.

Result: Not a system error, just an outdated page.

When: Keycloak cannot continue (error) or reports a completed action (info).

The error page shows Keycloak's message in a red box and, if the client has a start address, a button “Back to application”. The info page shows a message, if applicable the list of still open required actions, and a continue link.

Result: Typical case: a password link that was already used or has expired.

When: The user interface ends the Keycloak session without sending an ID token.

Keycloak asks whether you really want to sign out. With an ID token the question is skipped.

Result: See Signing out.

When: registrationAllowed is switched on in the realm. In the shipped realm file it is off.

The theme brings a page with first name, last name, email, if needed username, and password. Accounts created here bypass CIAS.

Result: At CodamAI, new accounts are created via Register and verify.

Adding the theme to Keycloak

The theme is static: FreeMarker templates, language files, a stylesheet and a small script (show password, language menu). The stylesheet resources/css/styles.css is built with Tailwind from src/main.css (npm run build).

  1. Put the folder theme/codamai into Keycloak’s theme directory (/opt/keycloak/themes/codamai).
  2. In the realm, select codamai under Realm settings → Themes → Login theme.

The realm file from cias-runtime does not set a login theme. Without this selection, Keycloak shows its stock pages. The flow is the same.

Pitfalls

Next

Sources in the code and the knowledge base
  • hub-login – theme/codamai/login/theme.properties, template.ftl, login.ftl, login-username.ftl, login-password.ftl, login-reset-password.ftl, login-update-password.ftl, login-verify-email.ftl, login-otp.ftl, login-page-expired.ftl, register.ftl, error.ftl, info.ftl, logout-confirm.ftl, messages/messages_de.properties, messages_en.properties, README.md
  • CIAS/cias-runtime – deploy/keycloak/import/codamai-realm.json (registrationAllowed, resetPasswordAllowed, verifyEmail, loginWithEmailAllowed), docker-compose.yml
  • CIAS/cias-iam-keycloak – KeycloakIdentityAdapter (UPDATE_PASSWORD)
  • CIAS/cias-iam-keycloak-provider – ActionLinkResource
  • hub-frontend, CIAS/cias-frontend – app/pages/login.vue
Search