Skip to content

Feature keycloak theme merged#84

Merged
kingazm merged 2 commits intomainfrom
feature-keycloak-theme-merged
Apr 16, 2026
Merged

Feature keycloak theme merged#84
kingazm merged 2 commits intomainfrom
feature-keycloak-theme-merged

Conversation

@cssma
Copy link
Copy Markdown
Collaborator

@cssma cssma commented Mar 22, 2026

📄 Pull Request Description


🧩 What was changed?

Added a custom Keycloak theme to the frontend repository under keycloak-theme/.


💡 Why was it changed?

JUCanEat/documentation#17


⚙️ How was it implemented?

The theme was built using Keycloakify — a library that allows writing Keycloak pages in React. It compiles to a JAR file that Keycloak loads as a provider.

To build the theme locally:

  1. cd keycloak-theme
  2. npm install
  3. npm run build-keycloak-theme
  4. Copy dist_keycloak/keycloak-theme-for-kc-22-to-25.jar to java-backend/docker/keycloak/providers/
    (once the backend PR with the updated volume mount is merged)
  5. Restart Keycloak: docker compose restart keycloak

⚠️ Side Effects or Risks

  • Every team member needs to build the JAR locally after pulling this branch — without it Keycloak will start but without the custom theme
  • The theme has its own package.json and node_modules inside keycloak-theme/ — it is a self-contained project within the repository

✅ Checklist

  • All 4 sections above are clearly filled out
  • Tests and documentation updated

@cssma cssma requested review from haniazipser and kingazm March 22, 2026 18:03
@kingazm
Copy link
Copy Markdown
Collaborator

kingazm commented Mar 27, 2026

Can we have these messages look more for human eyes in UI instead of this invalidUserMessage?
image

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a self-contained Keycloak theme project (built with Keycloakify + React/Vite) to the frontend repo so Keycloak can load a custom “jucaneat” login experience.

Changes:

  • Introduces a new keycloak-theme/ subproject with its own build tooling and dependencies to produce a Keycloak theme JAR.
  • Implements custom UI for multiple Keycloak login-related pages (login/register/reset/update password/verify email/error).
  • Minor formatting-only change in the existing app/routes/not-found.tsx.

Reviewed changes

Copilot reviewed 9 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
keycloak-theme/vite.config.ts Vite config including Keycloakify plugin + theme name.
keycloak-theme/tsconfig.json TypeScript config for the theme subproject.
keycloak-theme/src/vite-env.d.ts Vite client type references.
keycloak-theme/src/main.tsx React entrypoint wiring kcContext into the theme pages (includes mock context).
keycloak-theme/src/login/styles.css Theme styling for the login-related pages.
keycloak-theme/src/login/KcPage.tsx Page router + implementations for Keycloak login flows.
keycloak-theme/src/kc.gen.tsx Keycloakify auto-generated theme wiring/types.
keycloak-theme/package.json Theme subproject scripts/dependencies (build + keycloakify build).
keycloak-theme/package-lock.json Lockfile for the theme subproject.
keycloak-theme/index.html Vite HTML entry.
keycloak-theme/.gitignore Ignores node_modules and build outputs for theme.
app/routes/not-found.tsx Whitespace/indentation fix at EOF.
Files not reviewed (1)
  • keycloak-theme/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
} as any;

const kcContext = window.kcContext ?? mockKcContext;
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kcContext falls back to mockKcContext unconditionally. In a real Keycloak render, missing window.kcContext usually indicates misconfiguration; using mock data can mask the issue (and results in forms posting to #). Consider only using the mock in dev mode (e.g., import.meta.env.DEV) and otherwise throwing/rendering a clear error when window.kcContext is undefined.

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +30
/**
* NOTE: Do not import this type except maybe in your entrypoint.
* If you need to import the KcContext import it either from src/login/KcContext.ts or src/account/KcContext.ts.
* Depending on the theme type you are working on.
*/
export type KcContext =
| import("./login/KcContext").KcContext
;
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generated type references ./login/KcContext, but there is no keycloak-theme/src/login/KcContext.ts(x) in the repo. Even if it’s type-only, this makes the guidance in the comment block inaccurate and can confuse consumers of the generated API. Either commit the missing src/login/KcContext file (if keycloakify expects it) or regenerate/configure kc.gen.tsx so it references the actual keycloakify/login/KcContext type you’re using elsewhere.

Copilot uses AI. Check for mistakes.
Comment thread keycloak-theme/src/login/KcPage.tsx Outdated
Comment on lines +44 to +50
<label>Email</label>
<input
type="text"
name="username"
autoComplete="username"
required
/>
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The label isn’t associated with its input (no htmlFor + matching input id, and the input isn’t nested inside the label). This reduces screen-reader usability and click-to-focus behavior. Add id to the input and htmlFor to the label (same pattern applies to other fields in this file).

Copilot uses AI. Check for mistakes.
Comment thread keycloak-theme/src/login/KcPage.tsx Outdated
Comment on lines +332 to +334
<a className="btn primary" style={{ display: "block", textAlign: "center" }} href={url.loginAction}>
Resend Email
</a>
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url.loginAction is generally intended to be used as a form POST action. Using it as an <a href> will issue a GET and may not trigger the resend action. Consider switching this to a <form method="post" action={url.loginAction}> with a submit button so it matches Keycloak’s expected flow.

Copilot uses AI. Check for mistakes.
Comment thread keycloak-theme/src/login/KcPage.tsx Outdated
Comment on lines +105 to +107
function RegisterPage({ kcContext }: { kcContext: KcContext & { pageId: "register.ftl" } }) {
const { url, message, profile, messagesPerField } = kcContext as any;
const attrs = profile?.attributesByName ?? {};
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kcContext as any drops type safety for the register page and makes it easier to accidentally access non-existent properties. Prefer using the page-specific Keycloakify context type for register.ftl (or a type guard) so url.registrationAction, profile, and messagesPerField are typed without any.

Copilot uses AI. Check for mistakes.
Comment on lines +58 to +59
// NOTE: This is exported here only because in Webpack environnement it works differently
export const BASE_URL = import.meta.env.BASE_URL
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "environnement" should be "environment".

Copilot uses AI. Check for mistakes.
Comment thread keycloak-theme/src/login/KcPage.tsx Outdated
Comment on lines +322 to +326
{message && (
<div className={message.type === "error" ? "error" : "error"}>
{message.summary}
</div>
)}
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional for the message class is currently redundant (message.type === "error" ? "error" : "error") and will style non-error messages as errors. Use distinct classes (or at least different styling) based on message.type, or simplify if only errors are expected on this page.

Copilot uses AI. Check for mistakes.
@kingazm
Copy link
Copy Markdown
Collaborator

kingazm commented Apr 10, 2026

Please fix this formating with <br> visible, it should not look like that:
image

@kingazm
Copy link
Copy Markdown
Collaborator

kingazm commented Apr 10, 2026

From my understanding, these changes are already in prod. When I created an account and tried to remind password, this fails with HTTP 500:
image

Is this due sth on backend not merged yet or a real issue? This happens still after your Keycloak backend PR merge. Please investigate and lmk. @cssma

Locally I do not see the error message but I am not getting any emails.

@kingazm
Copy link
Copy Markdown
Collaborator

kingazm commented Apr 10, 2026

Btw, it says "invalid username or password" but requests email on login @cssma this seems inconsistent
And why are we prompting for user to choose username when in UI username is same as email? We should either acknowledge the username user chooses on sign up, or change UI in profile to show actual username.

Copy link
Copy Markdown
Collaborator

@kingazm kingazm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments

@kingazm
Copy link
Copy Markdown
Collaborator

kingazm commented Apr 10, 2026

Light theme is looking cool, and responsive, gj on that

@kingazm
Copy link
Copy Markdown
Collaborator

kingazm commented Apr 10, 2026

The correct directory to put .jar is java-backend/docker/keycloak/providers

@cssma
Copy link
Copy Markdown
Collaborator Author

cssma commented Apr 12, 2026

From my understanding, these changes are already in prod. When I created an account and tried to remind password, this fails with HTTP 500: image

Is this due sth on backend not merged yet or a real issue? This happens still after your Keycloak backend PR merge. Please investigate and lmk. @cssma

Locally I do not see the error message but I am not getting any emails.

Locally it works after filling in the SMTP app password in Keycloak admin. The issue on prod is just the missing password.

@cssma
Copy link
Copy Markdown
Collaborator Author

cssma commented Apr 12, 2026

Btw, it says "invalid username or password" but requests email on login @cssma this seems inconsistent And why are we prompting for user to choose username when in UI username is same as email? We should either acknowledge the username user chooses on sign up, or change UI in profile to show actual username.

Fixed:) removed the Username field from registration (email is used as login), and changed the error message to 'Invalid email or password.' to be consistent with the UI.

@cssma
Copy link
Copy Markdown
Collaborator Author

cssma commented Apr 12, 2026

The correct directory to put .jar is java-backend/docker/keycloak/providers

I'll open a separate PR on the backend repo with the compose.yaml change.

@cssma cssma requested a review from kingazm April 12, 2026 14:18
Copy link
Copy Markdown
Collaborator

@kingazm kingazm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing error messages

@kingazm kingazm merged commit c85d5c7 into main Apr 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants