15856: Merge branch 'master' into 15856-illegal-chars-warning
[arvados-workbench2.git] / src / store / auth / auth-middleware.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Middleware } from "redux";
6 import { authActions, } from "./auth-action";
7 import { ServiceRepository, setAuthorizationHeader, removeAuthorizationHeader } from "~/services/services";
8 import { initSessions } from "~/store/auth/auth-action-session";
9 import { User } from "~/models/user";
10 import { RootState } from '~/store/store';
11 import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
12 import { WORKBENCH_LOADING_SCREEN } from '~/store/workbench/workbench-actions';
13
14 export const authMiddleware = (services: ServiceRepository): Middleware => store => next => action => {
15     // Middleware to update external state (local storage, window
16     // title) to ensure that they stay in sync with redux state.
17
18     authActions.match(action, {
19         INIT_USER: ({ user, token }) => {
20             // The "next" method passes the action to the next
21             // middleware in the chain, or the reducer.  That means
22             // after next() returns, the action has (presumably) been
23             // applied by the reducer to update the state.
24             next(action);
25
26             const state: RootState = store.getState();
27
28             if (state.auth.apiToken) {
29                 services.authService.saveApiToken(state.auth.apiToken);
30                 setAuthorizationHeader(services, state.auth.apiToken);
31             } else {
32                 services.authService.removeApiToken();
33                 removeAuthorizationHeader(services);
34             }
35
36             store.dispatch<any>(initSessions(services.authService, state.auth.remoteHostsConfig[state.auth.localCluster], user));
37             if (!user.isActive) {
38                 // As a special case, if the user is inactive, they
39                 // may be able to self-activate using the "activate"
40                 // method.  Note, for this to work there can't be any
41                 // unsigned user agreements, we assume the API server is just going to
42                 // rubber-stamp our activation request.  At some point in the future we'll
43                 // want to either add support for displaying/signing user
44                 // agreements or get rid of self-activation.
45                 // For more details, see:
46                 // https://doc.arvados.org/master/admin/user-management.html
47
48                 store.dispatch(progressIndicatorActions.START_WORKING(WORKBENCH_LOADING_SCREEN));
49                 services.userService.activate(user.uuid).then((user: User) => {
50                     store.dispatch(authActions.INIT_USER({ user, token }));
51                     store.dispatch(progressIndicatorActions.STOP_WORKING(WORKBENCH_LOADING_SCREEN));
52                 }).catch(() => {
53                     store.dispatch(progressIndicatorActions.STOP_WORKING(WORKBENCH_LOADING_SCREEN));
54                 });
55             }
56         },
57         SET_CONFIG: ({ config }) => {
58             document.title = `Arvados Workbench (${config.uuidPrefix})`;
59             next(action);
60         },
61         LOGOUT: ({ deleteLinkData }) => {
62             next(action);
63             if (deleteLinkData) {
64                 services.linkAccountService.removeAccountToLink();
65             }
66             services.authService.removeApiToken();
67             services.authService.removeUser();
68             removeAuthorizationHeader(services);
69             services.authService.logout();
70         },
71         default: () => next(action)
72     });
73 };