PoC SSO - Keycloak integration#3105
Conversation
- next step move to webserver module
| commonjs(), | ||
| ], | ||
| server: { | ||
| host: '0.0.0.0', |
There was a problem hiding this comment.
This allows dev-server to listen also to 127.0.0.1 instead of only localhost else local testing with SSO is not possible.
| @@ -1,3 +1,4 @@ | |||
| /// <reference types="vite/client" /> | |||
There was a problem hiding this comment.
Gives us types for import.meta.env.DEV etc
| "@iobroker/types": "^7.0.7", | ||
| "@alcalzone/release-script-plugin-license": "^3.7.0", | ||
| "@iobroker/dm-utils": "^1.0.10", | ||
| "@iobroker/eslint-config": "^2.0.1", |
There was a problem hiding this comment.
moved eslint config to the package root (was only present in adapter-react-v5), else the backend had no ESLint support at least for my setup.
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a proof-of-concept SSO integration with Keycloak, adding proxy support, UI controls, and callback handling.
- Exposes a
/ssoproxy in the dev server and adds an SSO button on the login page - Implements OIDC connect/disconnect buttons in the user edit dialog and updates related type signatures
- Handles SSO callback parameters in the main
Appcomponent and adds translation keys for Single-Sign On
Reviewed Changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/admin/src-admin/vite.config.ts | Enabled host 0.0.0.0 and added /sso proxy |
| packages/admin/src-admin/src/login/Login.tsx | Adjusted avatar rendering logic and added SSO login button |
| packages/admin/src-admin/src/i18n/* | Added “Single-Sign On” and “Disconnect Single-Sign On” keys |
| packages/admin/src-admin/src/components/Users/UserEditDialog.tsx | Added OIDC connect/disconnect buttons; updated saveData to return a promise |
| packages/admin/src-admin/src/App.tsx | Added componentDidUpdate to process SSO callback params |
| packages/adapter-react-v5/package.json | Removed unused @iobroker/eslint-config dev dependency |
| package.json | Reordered and added @iobroker/adapter-react-v5 dependency |
| window.loginHideLogo === 'false' || | ||
| (window.loginHideLogo === '@@loginHideLogo@@' && ( | ||
| <Avatar | ||
| sx={styles.avatar} | ||
| src="img/admin.svg" | ||
| /> | ||
| ) | ||
| )) |
There was a problem hiding this comment.
Using logical OR here can render true in the JSX when loginHideLogo is 'false'. Replace with (cond1 || cond2) && <Avatar> so only the <Avatar> is rendered when either condition is met.
| "Discard": "Discard", | ||
| "Discard unsaved changes?": "Discard unsaved changes?", | ||
| "Discard?": "Discard?", | ||
| "Disconnect Single-Sign On'": "Disconnect Single-Sign On'", |
There was a problem hiding this comment.
Translation key has an extra trailing apostrophe. Remove the apostrophe so it matches your lookup string Disconnect Single-Sign On.
| "Disconnect Single-Sign On'": "Disconnect Single-Sign On'", | |
| "Disconnect Single-Sign On": "Disconnect Single-Sign On", |
| */ | ||
| renderOidcButton(): JSX.Element { | ||
| /* @ts-expect-error needs to be added to types */ | ||
| return this.props.user.common?.externalAuthentication?.oidc ? ( |
There was a problem hiding this comment.
The branches appear inverted: when oidc exists you render 'Add Single-Sign On', but it should likely render the disconnect button. Swap the branches or correct the labels.
| componentDidUpdate(): void { | ||
| // Due to the fact that the SSO process can only provide is parameters via a callback uri, we need to extract from the search parameters | ||
| // However, there might be a better place for this instead of using a side effect on every re-render |
There was a problem hiding this comment.
[nitpick] Parsing URL search parameters on every update can be inefficient. Consider moving this logic to componentDidMount or using a one-time effect.
| componentDidUpdate(): void { | |
| // Due to the fact that the SSO process can only provide is parameters via a callback uri, we need to extract from the search parameters | |
| // However, there might be a better place for this instead of using a side effect on every re-render | |
| componentDidMount(): void { | |
| // Due to the fact that the SSO process can only provide its parameters via a callback URI, we need to extract them from the search parameters |
- can only be turned on by editing the JSON right now as it is only for testing
| componentDidUpdate(): void { | ||
| // Due to the fact that the SSO process can only provide is parameters via a callback uri, we need to extract from the search parameters | ||
| // However, there might be a better place for this instead of using a side effect on every re-render |
| } | ||
|
|
||
| componentDidUpdate(): void { | ||
| // Due to the fact that the SSO process can only provide is parameters via a callback uri, we need to extract from the search parameters |
There was a problem hiding this comment.
is parameters => its parameters ?
this needs ioBroker/webserver#7