2021-05-31 16:46:41 +02:00
|
|
|
import { currentBackend } from '../backend';
|
2022-09-28 20:04:00 -06:00
|
|
|
import { addSnackbar } from '../store/slices/snackbars';
|
2021-05-31 16:46:41 +02:00
|
|
|
|
2021-05-31 14:23:16 +02:00
|
|
|
import type { AnyAction } from 'redux';
|
2022-10-20 11:57:30 -04:00
|
|
|
import type { ThunkDispatch } from 'redux-thunk';
|
|
|
|
import type { Credentials, User } from '../interface';
|
|
|
|
import type { RootState } from '../store';
|
2016-02-25 12:31:21 -08:00
|
|
|
|
|
|
|
export const AUTH_REQUEST = 'AUTH_REQUEST';
|
|
|
|
export const AUTH_SUCCESS = 'AUTH_SUCCESS';
|
|
|
|
export const AUTH_FAILURE = 'AUTH_FAILURE';
|
2017-11-11 12:30:24 -07:00
|
|
|
export const AUTH_REQUEST_DONE = 'AUTH_REQUEST_DONE';
|
2016-11-01 14:35:20 +01:00
|
|
|
export const LOGOUT = 'LOGOUT';
|
2016-02-25 12:31:21 -08:00
|
|
|
|
|
|
|
export function authenticating() {
|
|
|
|
return {
|
2016-11-01 14:35:20 +01:00
|
|
|
type: AUTH_REQUEST,
|
2020-12-13 13:35:07 +02:00
|
|
|
} as const;
|
2016-02-25 12:31:21 -08:00
|
|
|
}
|
|
|
|
|
2020-12-13 13:35:07 +02:00
|
|
|
export function authenticate(userData: User) {
|
2016-02-25 12:31:21 -08:00
|
|
|
return {
|
|
|
|
type: AUTH_SUCCESS,
|
2016-11-01 14:35:20 +01:00
|
|
|
payload: userData,
|
2020-12-13 13:35:07 +02:00
|
|
|
} as const;
|
2016-02-25 12:31:21 -08:00
|
|
|
}
|
|
|
|
|
2020-12-13 13:35:07 +02:00
|
|
|
export function authError(error: Error) {
|
2016-02-25 12:31:21 -08:00
|
|
|
return {
|
|
|
|
type: AUTH_FAILURE,
|
|
|
|
error: 'Failed to authenticate',
|
|
|
|
payload: error,
|
2020-12-13 13:35:07 +02:00
|
|
|
} as const;
|
2016-02-25 12:31:21 -08:00
|
|
|
}
|
|
|
|
|
2017-11-11 12:30:24 -07:00
|
|
|
export function doneAuthenticating() {
|
|
|
|
return {
|
|
|
|
type: AUTH_REQUEST_DONE,
|
2020-12-13 13:35:07 +02:00
|
|
|
} as const;
|
2017-11-11 12:30:24 -07:00
|
|
|
}
|
|
|
|
|
2016-11-01 14:35:20 +01:00
|
|
|
export function logout() {
|
|
|
|
return {
|
|
|
|
type: LOGOUT,
|
2020-12-13 13:35:07 +02:00
|
|
|
} as const;
|
2016-11-01 14:35:20 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 19:23:42 -02:00
|
|
|
// Check if user data token is cached and is valid
|
|
|
|
export function authenticateUser() {
|
2022-10-20 11:57:30 -04:00
|
|
|
return (dispatch: ThunkDispatch<RootState, {}, AnyAction>, getState: () => RootState) => {
|
2017-01-26 19:23:42 -02:00
|
|
|
const state = getState();
|
2022-10-20 11:57:30 -04:00
|
|
|
if (!state.config.config) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const backend = currentBackend(state.config.config);
|
|
|
|
|
2017-01-26 19:23:42 -02:00
|
|
|
dispatch(authenticating());
|
2020-12-13 13:35:07 +02:00
|
|
|
return Promise.resolve(backend.currentUser())
|
2018-08-07 14:46:54 -06:00
|
|
|
.then(user => {
|
2017-08-31 13:46:02 -06:00
|
|
|
if (user) {
|
|
|
|
dispatch(authenticate(user));
|
|
|
|
} else {
|
2017-11-11 12:30:24 -07:00
|
|
|
dispatch(doneAuthenticating());
|
2017-08-31 13:46:02 -06:00
|
|
|
}
|
2017-01-26 19:23:42 -02:00
|
|
|
})
|
2020-12-13 13:35:07 +02:00
|
|
|
.catch((error: Error) => {
|
2017-01-26 19:23:42 -02:00
|
|
|
dispatch(authError(error));
|
|
|
|
dispatch(logoutUser());
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-12-13 13:35:07 +02:00
|
|
|
export function loginUser(credentials: Credentials) {
|
2022-10-20 11:57:30 -04:00
|
|
|
return (dispatch: ThunkDispatch<RootState, {}, AnyAction>, getState: () => RootState) => {
|
2016-02-25 12:31:21 -08:00
|
|
|
const state = getState();
|
2022-10-20 11:57:30 -04:00
|
|
|
if (!state.config.config) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const backend = currentBackend(state.config.config);
|
2016-02-25 12:31:21 -08:00
|
|
|
|
|
|
|
dispatch(authenticating());
|
2018-08-07 14:46:54 -06:00
|
|
|
return backend
|
|
|
|
.authenticate(credentials)
|
|
|
|
.then(user => {
|
2016-11-01 14:35:20 +01:00
|
|
|
dispatch(authenticate(user));
|
2017-01-26 19:23:42 -02:00
|
|
|
})
|
2022-10-26 11:46:44 -04:00
|
|
|
.catch((error: unknown) => {
|
2018-11-02 10:29:11 -04:00
|
|
|
console.error(error);
|
2022-10-26 11:46:44 -04:00
|
|
|
if (error instanceof Error) {
|
|
|
|
dispatch(
|
|
|
|
addSnackbar({
|
|
|
|
type: 'warning',
|
|
|
|
message: {
|
|
|
|
key: 'ui.toast.onFailToAuth',
|
|
|
|
options: {
|
|
|
|
details: error.message,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
dispatch(authError(error));
|
|
|
|
}
|
2016-11-01 14:35:20 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function logoutUser() {
|
2022-10-20 11:57:30 -04:00
|
|
|
return (dispatch: ThunkDispatch<RootState, {}, AnyAction>, getState: () => RootState) => {
|
2016-11-01 14:35:20 +01:00
|
|
|
const state = getState();
|
2022-10-20 11:57:30 -04:00
|
|
|
if (!state.config.config) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const backend = currentBackend(state.config.config);
|
2017-09-05 19:30:03 -07:00
|
|
|
Promise.resolve(backend.logout()).then(() => {
|
|
|
|
dispatch(logout());
|
|
|
|
});
|
2016-02-25 12:31:21 -08:00
|
|
|
};
|
|
|
|
}
|
2020-12-13 13:35:07 +02:00
|
|
|
|
|
|
|
export type AuthAction = ReturnType<
|
|
|
|
| typeof authenticating
|
|
|
|
| typeof authenticate
|
|
|
|
| typeof authError
|
|
|
|
| typeof doneAuthenticating
|
|
|
|
| typeof logout
|
|
|
|
>;
|