Merge branch '18368-notification-banner' into 19836-new-tooltip-impl
[arvados-workbench2.git] / src / store / auth / auth-reducer.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { authActions, AuthAction } from "./auth-action";
6 import { User } from "models/user";
7 import { ServiceRepository } from "services/services";
8 import { SshKeyResource } from 'models/ssh-key';
9 import { Session } from "models/session";
10 import { Config, mockConfig } from 'common/config';
11
12 export interface AuthState {
13     user?: User;
14     apiToken?: string;
15     apiTokenExpiration?: Date;
16     apiTokenLocation?: string;
17     extraApiToken?: string;
18     extraApiTokenExpiration?: Date;
19     sshKeys: SshKeyResource[];
20     sessions: Session[];
21     localCluster: string;
22     homeCluster: string;
23     loginCluster: string;
24     remoteHosts: { [key: string]: string };
25     remoteHostsConfig: { [key: string]: Config };
26     config: Config;
27 }
28
29 const initialState: AuthState = {
30     user: undefined,
31     apiToken: undefined,
32     apiTokenExpiration: undefined,
33     apiTokenLocation: undefined,
34     extraApiToken: undefined,
35     extraApiTokenExpiration: undefined,
36     sshKeys: [],
37     sessions: [],
38     localCluster: "",
39     homeCluster: "",
40     loginCluster: "",
41     remoteHosts: {},
42     remoteHostsConfig: {},
43     config: mockConfig({})
44 };
45
46 export const authReducer = (services: ServiceRepository) => (state = initialState, action: AuthAction) => {
47     return authActions.match(action, {
48         SET_CONFIG: ({ config }) =>
49             ({
50                 ...state,
51                 config,
52                 localCluster: config.uuidPrefix,
53                 remoteHosts: {
54                     ...config.remoteHosts,
55                     [config.uuidPrefix]: new URL(config.rootUrl).host
56                 },
57                 homeCluster: config.loginCluster || config.uuidPrefix,
58                 loginCluster: config.loginCluster,
59                 remoteHostsConfig: {
60                     ...state.remoteHostsConfig,
61                     [config.uuidPrefix]: config
62                 }
63             }),
64         REMOTE_CLUSTER_CONFIG: ({ config }) =>
65             ({
66                 ...state,
67                 remoteHostsConfig: {
68                     ...state.remoteHostsConfig,
69                     [config.uuidPrefix]: config
70                 },
71             }),
72         SET_EXTRA_TOKEN: ({ extraApiToken, extraApiTokenExpiration }) =>
73             ({ ...state, extraApiToken, extraApiTokenExpiration }),
74         RESET_EXTRA_TOKEN: () =>
75             ({ ...state, extraApiToken: undefined, extraApiTokenExpiration: undefined }),
76         INIT_USER: ({ user, token, tokenExpiration, tokenLocation = state.apiTokenLocation }) =>
77             ({ ...state,
78                 user,
79                 apiToken: token,
80                 apiTokenExpiration: tokenExpiration,
81                 apiTokenLocation: tokenLocation,
82                 homeCluster: user.uuid.substring(0, 5)
83             }),
84         LOGIN: () => state,
85         LOGOUT: () => ({ ...state, apiToken: undefined }),
86         USER_DETAILS_SUCCESS: (user: User) =>
87             ({ ...state, user, homeCluster: user.uuid.substring(0, 5) }),
88         SET_SSH_KEYS: (sshKeys: SshKeyResource[]) => ({ ...state, sshKeys }),
89         ADD_SSH_KEY: (sshKey: SshKeyResource) =>
90             ({ ...state, sshKeys: state.sshKeys.concat(sshKey) }),
91         REMOVE_SSH_KEY: (uuid: string) =>
92             ({ ...state, sshKeys: state.sshKeys.filter((sshKey) => sshKey.uuid !== uuid) }),
93         SET_HOME_CLUSTER: (homeCluster: string) => ({ ...state, homeCluster }),
94         SET_SESSIONS: (sessions: Session[]) => ({ ...state, sessions }),
95         ADD_SESSION: (session: Session) =>
96             ({ ...state, sessions: state.sessions.concat(session) }),
97         REMOVE_SESSION: (clusterId: string) =>
98             ({
99                 ...state,
100                 sessions: state.sessions.filter(
101                     session => session.clusterId !== clusterId
102                 )
103             }),
104         UPDATE_SESSION: (session: Session) =>
105             ({
106                 ...state,
107                 sessions: state.sessions.map(
108                     s => s.clusterId === session.clusterId ? session : s
109                 )
110             }),
111         default: () => state
112     });
113 };