From 1abfab1ddebc5b2dbe81cf318ee2056b02f893c6 Mon Sep 17 00:00:00 2001 From: Benjamin Cavy Date: Wed, 23 Oct 2024 10:24:42 +0200 Subject: [PATCH] fix: wrong redirect / error display on OIDC login This also replace local mock for OIDC since old container did not work anymore. Fix #849 --- conf/dev.conf | 4 +- docker-compose.yml | 105 ++++++++++++++++++-- izanami-frontend/src/pages/login.tsx | 21 ++-- izanami-frontend/tests/oidc.spec.ts | 18 ++++ test/fr/maif/izanami/api/LoginAPISpec.scala | 39 +------- 5 files changed, 131 insertions(+), 56 deletions(-) create mode 100644 izanami-frontend/tests/oidc.spec.ts diff --git a/conf/dev.conf b/conf/dev.conf index 8d45018c9..9902b7f15 100644 --- a/conf/dev.conf +++ b/conf/dev.conf @@ -15,8 +15,8 @@ app { openid { client-id = foo client-secret = bar - authorize-url = "http://localhost:9001/auth" - token-url = "http://localhost:9001/token" + authorize-url = "http://localhost:9001/connect/authorize" + token-url = "http://localhost:9001/connect/token" redirect-url = "http://localhost:3000/login" scopes = "email profile" username-field = name diff --git a/docker-compose.yml b/docker-compose.yml index ae089c855..a212e3921 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,99 @@ version: '3.1' services: + oidc-server-mock: + container_name: oidc-server-mock + image: ghcr.io/soluto/oidc-server-mock:latest + ports: + - '9001:8080' + environment: + ASPNETCORE_ENVIRONMENT: Development + SERVER_OPTIONS_INLINE: | + { + "AccessTokenJwtType": "JWT", + "Discovery": { + "ShowKeySet": true + }, + "Authentication": { + "CookieSameSiteMode": "Lax", + "CheckSessionCookieSameSiteMode": "Lax" + } + } + LOGIN_OPTIONS_INLINE: | + { + "AllowRememberLogin": false + } + LOGOUT_OPTIONS_INLINE: | + { + "AutomaticRedirectAfterSignOut": true + } + API_SCOPES_INLINE: | + - Name: some-app-scope-1 + - Name: some-app-scope-2 + API_RESOURCES_INLINE: | + - Name: some-app + Scopes: + - some-app-scope-1 + - some-app-scope-2 + USERS_CONFIGURATION_INLINE: | + [ + { + "SubjectId":"1", + "Username":"User1", + "Password":"pwd", + "Claims": [ + { + "Type": "name", + "Value": "Sam Tailor", + "ValueType": "string" + }, + { + "Type": "email", + "Value": "sam.tailor@gmail.com", + "ValueType": "string" + }, + { + "Type": "some-api-resource-claim", + "Value": "Sam's Api Resource Custom Claim", + "ValueType": "string" + }, + { + "Type": "some-api-scope-claim", + "Value": "Sam's Api Scope Custom Claim", + "ValueType": "string" + }, + { + "Type": "some-identity-resource-claim", + "Value": "Sam's Identity Resource Custom Claim", + "ValueType": "string" + } + ] + } + ] + CLIENTS_CONFIGURATION_INLINE: | + [ + { + "ClientId": "foo", + "ClientSecrets": ["bar"], + "Description": "Client for implicit flow", + "AllowedGrantTypes": ["authorization_code"], + "RequirePkce": false, + "AllowAccessTokensViaBrowser": true, + "RedirectUris": ["http://localhost:3000/login"], + "AllowedScopes": ["openid", "profile", "email"], + "IdentityTokenLifetime": 3600, + "AccessTokenLifetime": 3600, + "AlwaysIncludeUserClaimsInIdToken": true + } + ] + ASPNET_SERVICES_OPTIONS_INLINE: | + { + "ForwardedHeadersOptions": { + "ForwardedHeaders" : "All" + } + } + volumes: + - .:/tmp/config:ro db: image: postgres restart: always @@ -12,12 +105,12 @@ services: # - ./schema.sql:/docker-entrypoint-initdb.d/schema.sql ports: - 5432:5432 - openid: - image: qlik/simple-oidc-provider - environment: - REDIRECTS: http://localhost:3000/login - ports: - - 9001:9000 + #openid: + # image: qlik/simple-oidc-provider + # environment: + # REDIRECTS: http://localhost:3000/login + # ports: + # - 9001:9000 fake-smtp: image: reachfive/fake-smtp-server ports: diff --git a/izanami-frontend/src/pages/login.tsx b/izanami-frontend/src/pages/login.tsx index 4c685b5ba..da8943d98 100644 --- a/izanami-frontend/src/pages/login.tsx +++ b/izanami-frontend/src/pages/login.tsx @@ -53,27 +53,28 @@ function TokenWaitScreen({ code }: { code: string }) { } } - function LoginForm(props: { req?: string }) { const navigate = useNavigate(); const req = props.req; const { setUser, integrations, expositionUrl } = useContext(IzanamiContext); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); - const [lightMode, setLightMode] = useState(false) - + const [lightMode, setLightMode] = useState(false); + React.useEffect(() => { let mode = window.localStorage.getItem("izanami-dark-light-mode"); setLightMode(mode !== "dark"); - if (mode === "light") {document.documentElement.setAttribute("data-theme", "light")} - },[]) + if (mode === "light") { + document.documentElement.setAttribute("data-theme", "light"); + } + }, []); const handleCheckboxChange = (event: React.ChangeEvent) => { setLightMode(event.target.checked); if (lightMode) { - document.documentElement.setAttribute("data-theme", "dark") + document.documentElement.setAttribute("data-theme", "dark"); window.localStorage.setItem("izanami-dark-light-mode", "dark"); - }else{ + } else { document.documentElement.setAttribute("data-theme", "light"); window.localStorage.setItem("izanami-dark-light-mode", "light"); } @@ -186,6 +187,7 @@ function LoginForm(props: { req?: string }) {
OR