saasufy-components 10.2.0 → 10.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +23 -0
  2. package/log-out.js +44 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -936,6 +936,8 @@ The change in the location hash can then be detected by an `app-router` to switc
936
936
 
937
937
  A component which can be placed inside a `socket-provider` to deauthenticate the socket (e.g. on click).
938
938
 
939
+ If the user logged in via an OAuth provider which supports RP-initiated log out (such as Keycloak), deauthenticating the socket does not end the session on the provider itself; the user would be logged straight back in without being asked for their credentials the next time they log in. To also end the provider session, specify the `logout-url` attribute and the component will redirect the user to that endpoint after deauthenticating the socket.
940
+
939
941
  **Import**
940
942
 
941
943
  ```html
@@ -948,6 +950,27 @@ A component which can be placed inside a `socket-provider` to deauthenticate the
948
950
  <log-out onclick="logOut()"><a href="javascript:void(0)">Log out</a></log-out>
949
951
  ```
950
952
 
953
+ Logging out of Keycloak as well as of the app:
954
+
955
+ ```html
956
+ <log-out
957
+ onclick="logOut()"
958
+ provider="keycloak"
959
+ logout-url="https://auth.example.com/realms/myrealm/protocol/openid-connect/logout"
960
+ client-id="myclient"
961
+ post-logout-redirect-uri="https://myapp.com/index.html"
962
+ ><a href="javascript:void(0)">Log out</a></log-out>
963
+ ```
964
+
965
+ **Attributes**
966
+
967
+ - `logout-url`: The log out endpoint of the OAuth provider; for OpenID Connect providers this is the `end_session_endpoint`. If it is not specified, the component only deauthenticates the socket. The redirect is skipped if the user did not log in via an OAuth provider.
968
+ - `provider`: The name of the OAuth provider, as specified on the `Authentication` page of your Saasufy control panel. If it is set, the redirect only happens when the user logged in via that specific provider; this is useful when your app offers several different ways to log in.
969
+ - `client-id`: The client ID to pass to the provider as the `client_id` query parameter. OpenID Connect providers require either this or an ID token in order to log the user out without asking them to confirm.
970
+ - `post-logout-redirect-uri`: The URL to send the user back to once the provider has logged them out, passed as the `post_logout_redirect_uri` query parameter. It usually needs to be registered with the provider in advance. If it is not specified, the user is left on the provider's own logged out page.
971
+
972
+ If the auth token contains an ID token (which requires the `idTokenField` of the provider to be set on the `Authentication` page of your Saasufy control panel), it is passed to the provider as the `id_token_hint` query parameter. Providers such as Keycloak show a log out confirmation page when it is missing. Any of these query parameters which are already present in `logout-url` are left untouched.
973
+
951
974
  ### oauth-link
952
975
 
953
976
  A link to initiate an OAuth flow to authenticate a user as part of log in. Can support a range of different OAuth providers.
package/log-out.js CHANGED
@@ -1,8 +1,50 @@
1
1
  import { SocketConsumer } from './socket.js';
2
2
 
3
3
  class LogOut extends SocketConsumer {
4
- logOut() {
5
- this.getSocket().deauthenticate();
4
+ getProviderLogOutURL(authToken) {
5
+ let logoutURL = this.getAttribute('logout-url');
6
+ if (!logoutURL) return null;
7
+
8
+ // RP-initiated log out only applies to sessions which were created via an OAuth provider.
9
+ let authSource = authToken && authToken.authSource;
10
+ if (!authSource) return null;
11
+ let provider = this.getAttribute('provider');
12
+ if (provider && provider !== authSource) return null;
13
+
14
+ let providerLogOutURL;
15
+ try {
16
+ providerLogOutURL = new URL(logoutURL, location.origin);
17
+ } catch (error) {
18
+ throw new Error(
19
+ 'The logout-url attribute of log-out was not a valid URL'
20
+ );
21
+ }
22
+
23
+ let clientId = this.getAttribute('client-id');
24
+ let postLogoutRedirectURI = this.getAttribute('post-logout-redirect-uri');
25
+ let searchParams = providerLogOutURL.searchParams;
26
+
27
+ // Without an id_token_hint, the provider asks the user to confirm the log out.
28
+ if (authToken.idToken && !searchParams.has('id_token_hint')) {
29
+ searchParams.set('id_token_hint', authToken.idToken);
30
+ }
31
+ if (clientId && !searchParams.has('client_id')) {
32
+ searchParams.set('client_id', clientId);
33
+ }
34
+ if (postLogoutRedirectURI && !searchParams.has('post_logout_redirect_uri')) {
35
+ searchParams.set('post_logout_redirect_uri', postLogoutRedirectURI);
36
+ }
37
+ return providerLogOutURL.href;
38
+ }
39
+
40
+ async logOut() {
41
+ let socket = this.getSocket();
42
+ // The auth token must be read before the socket is deauthenticated.
43
+ let providerLogOutURL = this.getProviderLogOutURL(socket.authToken);
44
+ await socket.deauthenticate();
45
+ if (providerLogOutURL) {
46
+ location.href = providerLogOutURL;
47
+ }
6
48
  }
7
49
  }
8
50
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasufy-components",
3
- "version": "10.2.0",
3
+ "version": "10.2.1",
4
4
  "description": "Components for Saasufy.",
5
5
  "main": "index.js",
6
6
  "scripts": {