Browse Source

feat: Adds auto redirect config for token auth URL.

Option that enables auto redirect, so once a user has authenticated we will use that authentication on next join.
factor2
damencho 2 years ago
parent
commit
06f509b475

+ 1
- 0
config.js View File

@@ -1447,6 +1447,7 @@ var config = {
1447 1447
      peopleSearchUrl
1448 1448
      requireDisplayName
1449 1449
      tokenAuthUrl
1450
+     tokenAuthUrlAutoRedirect
1450 1451
      tokenLogoutUrl
1451 1452
      */
1452 1453
 

+ 10
- 0
react/features/authentication/actionTypes.ts View File

@@ -26,6 +26,16 @@ export const LOGIN = 'LOGIN';
26 26
  */
27 27
 export const LOGOUT = 'LOGOUT';
28 28
 
29
+/**
30
+ * The type of (redux) action which signals that we have authenticated successful when
31
+ * tokenAuthUrl is set.
32
+ *
33
+ * {
34
+ *     type: SET_TOKEN_AUTH_URL_SUCCESS
35
+ * }
36
+ */
37
+export const SET_TOKEN_AUTH_URL_SUCCESS = 'SET_TOKEN_AUTH_URL_SUCCESS';
38
+
29 39
 /**
30 40
  * The type of (redux) action which signals that the cyclic operation of waiting
31 41
  * for conference owner has been aborted.

+ 14
- 0
react/features/authentication/actions.any.ts View File

@@ -4,6 +4,7 @@ import { IJitsiConference } from '../base/conference/reducer';
4 4
 import { hideDialog, openDialog } from '../base/dialog/actions';
5 5
 
6 6
 import {
7
+    SET_TOKEN_AUTH_URL_SUCCESS,
7 8
     STOP_WAIT_FOR_OWNER,
8 9
     UPGRADE_ROLE_FINISHED,
9 10
     UPGRADE_ROLE_STARTED, WAIT_FOR_OWNER
@@ -185,3 +186,16 @@ export function waitForOwner() {
185 186
 export function openLoginDialog() {
186 187
     return openDialog(LoginDialog);
187 188
 }
189
+
190
+/**
191
+ * Updates the config with new options.
192
+ *
193
+ * @param {boolean} value - The new value.
194
+ * @returns {Function}
195
+ */
196
+export function setTokenAuthUrlSuccess(value: boolean) {
197
+    return {
198
+        type: SET_TOKEN_AUTH_URL_SUCCESS,
199
+        value
200
+    };
201
+}

+ 55
- 8
react/features/authentication/middleware.ts View File

@@ -2,7 +2,8 @@ import { IStore } from '../app/types';
2 2
 import {
3 3
     CONFERENCE_FAILED,
4 4
     CONFERENCE_JOINED,
5
-    CONFERENCE_LEFT
5
+    CONFERENCE_LEFT,
6
+    SET_ROOM
6 7
 } from '../base/conference/actionTypes';
7 8
 import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../base/connection/actionTypes';
8 9
 import { hangup } from '../base/connection/actions';
@@ -31,8 +32,10 @@ import {
31 32
     openLoginDialog,
32 33
     openWaitForOwnerDialog,
33 34
     redirectToDefaultLocation,
35
+    setTokenAuthUrlSuccess,
34 36
     stopWaitForOwner,
35
-    waitForOwner } from './actions';
37
+    waitForOwner
38
+} from './actions';
36 39
 import { LoginDialog, WaitForOwnerDialog } from './components';
37 40
 import { getTokenAuthUrl, isTokenAuthEnabled } from './functions';
38 41
 
@@ -107,12 +110,25 @@ MiddlewareRegistry.register(store => next => action => {
107 110
         break;
108 111
     }
109 112
 
110
-    case CONFERENCE_JOINED:
113
+    case CONFERENCE_JOINED: {
114
+        const { dispatch, getState } = store;
115
+        const state = getState();
116
+        const config = state['features/base/config'];
117
+
118
+        if (isTokenAuthEnabled(config)
119
+            && config.tokenAuthUrlAutoRedirect
120
+            && state['features/base/jwt'].jwt) {
121
+            // auto redirect is turned on and we have succesfully logged in
122
+            // let's mark that
123
+            dispatch(setTokenAuthUrlSuccess(true));
124
+        }
125
+
111 126
         if (_isWaitingForOwner(store)) {
112 127
             store.dispatch(stopWaitForOwner());
113 128
         }
114 129
         store.dispatch(hideLoginDialog());
115 130
         break;
131
+    }
116 132
 
117 133
     case CONFERENCE_LEFT:
118 134
         store.dispatch(stopWaitForOwner());
@@ -146,14 +162,24 @@ MiddlewareRegistry.register(store => next => action => {
146 162
     }
147 163
 
148 164
     case LOGOUT: {
165
+        const { dispatch, getState } = store;
166
+        const state = getState();
167
+        const config = state['features/base/config'];
149 168
         const { conference } = store.getState()['features/base/conference'];
150 169
 
151 170
         if (!conference) {
152 171
             break;
153 172
         }
154 173
 
155
-        store.dispatch(openLogoutDialog(() => {
156
-            const logoutUrl = store.getState()['features/base/config'].tokenLogoutUrl;
174
+        dispatch(openLogoutDialog(() => {
175
+            const logoutUrl = config.tokenLogoutUrl;
176
+
177
+            if (isTokenAuthEnabled(config)
178
+                && config.tokenAuthUrlAutoRedirect
179
+                && state['features/base/jwt'].jwt) {
180
+                // user is logging out remove auto redirect indication
181
+                dispatch(setTokenAuthUrlSuccess(false));
182
+            }
157 183
 
158 184
             if (logoutUrl) {
159 185
                 window.location.href = logoutUrl;
@@ -161,12 +187,31 @@ MiddlewareRegistry.register(store => next => action => {
161 187
                 return;
162 188
             }
163 189
 
164
-            conference.room.moderator.logout(() => store.dispatch(hangup(true)));
190
+            conference.room.moderator.logout(() => dispatch(hangup(true)));
165 191
         }));
166 192
 
167 193
         break;
168 194
     }
169 195
 
196
+    case SET_ROOM: {
197
+        const { dispatch, getState } = store;
198
+        const state = getState();
199
+        const config = state['features/base/config'];
200
+
201
+        if (isTokenAuthEnabled(config) && config.tokenAuthUrlAutoRedirect
202
+            && state['features/authentication'].tokenAuthUrlSuccessful) {
203
+            // if we have auto redirect enabled, and we have previously logged in successfully
204
+            // let's redirect to the auth url to get the token and login again
205
+            dispatch(setTokenAuthUrlSuccess(false));
206
+
207
+            const { room } = action;
208
+
209
+            window.location.href = getTokenAuthUrl(config)(room, false);
210
+        }
211
+
212
+        break;
213
+    }
214
+
170 215
     case STOP_WAIT_FOR_OWNER:
171 216
         _clearExistingWaitForOwnerTimeout(store);
172 217
         store.dispatch(hideDialog(WaitForOwnerDialog));
@@ -248,8 +293,10 @@ function _handleLogin({ dispatch, getState }: IStore) {
248 293
         }
249 294
 
250 295
         // FIXME: This method will not preserve the other URL params that were originally passed.
251
-        // redirectToTokenAuthService
252
-        window.location.href = getTokenAuthUrl(config)(room, false);
296
+        const tokenAuthServiceUrl = getTokenAuthUrl(config)(room, false);
297
+
298
+        // we have already shown the prejoin screen so no need to show it again(if enabled) after obtaining the token
299
+        window.location.href = `${tokenAuthServiceUrl}${tokenAuthServiceUrl.includes('#') ? '&' : '#'}skipPrejoin=true`;
253 300
     } else {
254 301
         dispatch(openLoginDialog());
255 302
     }

+ 14
- 0
react/features/authentication/reducer.ts View File

@@ -1,8 +1,10 @@
1
+import PersistenceRegistry from '../base/redux/PersistenceRegistry';
1 2
 import ReducerRegistry from '../base/redux/ReducerRegistry';
2 3
 import { assign } from '../base/redux/functions';
3 4
 
4 5
 import {
5 6
     CANCEL_LOGIN,
7
+    SET_TOKEN_AUTH_URL_SUCCESS,
6 8
     STOP_WAIT_FOR_OWNER,
7 9
     UPGRADE_ROLE_FINISHED,
8 10
     UPGRADE_ROLE_STARTED,
@@ -15,9 +17,17 @@ export interface IAuthenticationState {
15 17
     thenableWithCancel?: {
16 18
         cancel: Function;
17 19
     };
20
+    tokenAuthUrlSuccessful?: boolean;
18 21
     waitForOwnerTimeoutID?: number;
19 22
 }
20 23
 
24
+/**
25
+ * Sets up the persistence of the feature {@code authentication}.
26
+ */
27
+PersistenceRegistry.register('features/authentication', {
28
+    tokenAuthUrlSuccessful: true
29
+});
30
+
21 31
 /**
22 32
  * Listens for actions which change the state of the authentication feature.
23 33
  *
@@ -35,6 +45,10 @@ ReducerRegistry.register<IAuthenticationState>('features/authentication',
35 45
             progress: undefined,
36 46
             thenableWithCancel: undefined
37 47
         });
48
+    case SET_TOKEN_AUTH_URL_SUCCESS:
49
+        return assign(state, {
50
+            tokenAuthUrlSuccessful: action.value
51
+        });
38 52
 
39 53
     case STOP_WAIT_FOR_OWNER:
40 54
         return assign(state, {

+ 1
- 0
react/features/base/config/configType.ts View File

@@ -576,6 +576,7 @@ export interface IConfig {
576 576
         numberOfVisibleTiles?: number;
577 577
     };
578 578
     tokenAuthUrl?: string;
579
+    tokenAuthUrlAutoRedirect?: string;
579 580
     tokenLogoutUrl?: string;
580 581
     toolbarButtons?: Array<ToolbarButtons>;
581 582
     toolbarConfig?: {

Loading…
Cancel
Save