From 2bdf7c5c4e5ea88f1da85bc71a4a6f2d9ff08f6f Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Tue, 25 Feb 2025 17:23:14 +0100 Subject: [PATCH] NORY-46: add 'OpenID Connect logout' section --- .../src/components/forms/client-form.tsx | 191 ++++++++++++++++++ dashboard/src/lib/forms/client-form.ts | 7 +- 2 files changed, 197 insertions(+), 1 deletion(-) diff --git a/dashboard/src/components/forms/client-form.tsx b/dashboard/src/components/forms/client-form.tsx index 4ef7693..fc5d6be 100644 --- a/dashboard/src/components/forms/client-form.tsx +++ b/dashboard/src/components/forms/client-form.tsx @@ -25,7 +25,9 @@ interface CreateClientFormProps { export function CreateClientForm({ action }: CreateClientFormProps) { const router = useRouter(); + const [redirectUris, setRedirectUris] = useState(['']); + const [postLogoutRedirectUris, setPostLogoutRedirectUris] = useState(['']); const form = useForm>({ resolver: zodResolver(clientFormSchema), @@ -62,12 +64,22 @@ export function CreateClientForm({ action }: CreateClientFormProps) { setRedirectUris([...redirectUris, '']); }; + const addPostLogoutRedirectUri = () => { + setPostLogoutRedirectUris([...postLogoutRedirectUris, '']); + }; + const removeRedirectUri = (index: number) => { const updatedRedirectUris = redirectUris.filter((_, i) => i !== index); setRedirectUris(updatedRedirectUris); form.setValue('redirect_uris', updatedRedirectUris); }; + const removePostLogoutRedirectUri = (index: number) => { + const updatedPostLogoutRedirectUris = postLogoutRedirectUris.filter((_, i) => i !== index); + setPostLogoutRedirectUris(postLogoutRedirectUris); + form.setValue('post_logout_redirect_uris', updatedPostLogoutRedirectUris); + }; + const handleInputChange = (index: number, event: any) => { const updatedRedirectUris = [...redirectUris]; updatedRedirectUris[index] = event.target.value; @@ -75,6 +87,13 @@ export function CreateClientForm({ action }: CreateClientFormProps) { form.setValue('redirect_uris', updatedRedirectUris); }; + const handlePostLogoutInputChange = (index: number, event: any) => { + const updatedPostLogoutRedirectUris = [...postLogoutRedirectUris]; + updatedPostLogoutRedirectUris[index] = event.target.value; + setPostLogoutRedirectUris(updatedPostLogoutRedirectUris); + form.setValue('post_logout_redirect_uris', updatedPostLogoutRedirectUris); + }; + return ( <> { @@ -384,6 +403,178 @@ export function CreateClientForm({ action }: CreateClientFormProps) { + + + + OpenID Connect logout + + + Get more information about using front and backchannels here  + . + + + + ( + +
+ + Frontchannel Logout Session Required + + + Boolean value specifying whether the Relay Party (RP) requires that + issuer and session ID query parameters be included to identify the RP + session with the OpenID provider (OP) when the Frontchannel Logout URI + is used. The default value is false. + +
+ + + +
+ )} + /> + ( + + Frontchannel Logout URI + + URL that will cause the Relying Party (RP) to log itself out when rendered + in an iframe by the OpenID provider (OP). An issuer query parameter and a + session ID query parameter MAY be included by the OpenID provider (OP) to + enable the Relying Party (RP) to validate the request and to determine which + of the potentially multiple sessions is to be logged out; if either is + included, both MUST be. + + + + + + + )} + /> + ( + +
+ + Backchannel Logout Session Required + + + Boolean value specifying whether the Relying Party (RP) requires that a + session ID Claim be included in the Logout Token to identify the Relying + Party session with the OpenID provider (OP) when the Backchannel Logout + URI is used. If omitted, the default value is false. + +
+ + + +
+ )} + /> + ( + + Backchannel Logout URI + + URL that will cause the Relying Party (RP) to log itself out when rendered + in an iframe by the OpenID provider (OP). An issuer query parameter and a + session ID query parameter MAY be included by the OpenID provider (OP) to + enable the Relying Party (RP) to validate the request and to determine which + of the potentially multiple sessions is to be logged out; if either is + included, both MUST be. + + + + + + + )} + /> + ( + +
+ + Skip logout consent + + + Boolean value specifying whether the additional logout consent screen + should be skipped. + +
+ + + +
+ )} + /> + {postLogoutRedirectUris.map((uri, index) => ( +
+ + + Post Logout Redirect URI {index + 1} + +
+ handlePostLogoutInputChange(index, event)} + /> + {postLogoutRedirectUris.length > 1 && ( + + )} +
+
+ {form.formState.errors?.post_logout_redirect_uris && form.formState.errors.post_logout_redirect_uris[index] && ( + {form.formState.errors.post_logout_redirect_uris[index].message} + )} +
+
+ ))} + + +
+
+