@tesler-ui/cra-template-typescript
Version:
The base TypeScript template for Create React App.
68 lines (61 loc) • 2.4 kB
text/typescript
import { CustomEpic, actionTypes, AnyAction } from '../interfaces/actions'
import { getBasicAuthRequest } from '../api/session'
import { LoginResponse } from '@tesler-ui/core/interfaces/session'
import { Observable } from 'rxjs/Observable'
import { $do, SSO_AUTH } from '../actions/types'
import { AxiosError } from 'axios'
import { AppState } from "../interfaces/storeSlices";
import { Epic } from "redux-observable";
import { keycloak, keycloakOptions } from '../keycloak'
const responseStatusMessages: Record<number, string> = {
401: 'Unauthorized',
403: 'Access denied'
}
const ssoAuthEpic: Epic<AnyAction, AppState> = (action$, store) =>
action$.ofType(SSO_AUTH).switchMap(() => {
return Observable.fromPromise(keycloak.init(keycloakOptions))
.switchMap(() => Observable.of($do.login({ login: '', password: '' })))
.catch(() => {
console.error('Authentication failed')
return Observable.empty<never>()
})
})
const loginEpic: CustomEpic = (action$, store) => action$.ofType(actionTypes.login)
.filter(action => !action.payload?.role)
.switchMap((action) => {
const login = action.payload && action.payload.login
const password = action.payload && action.payload.password
return getBasicAuthRequest(login, password)
.mergeMap((data: LoginResponse) => {
return Observable.of($do.loginDone({
devPanelEnabled: data.devPanelEnabled,
activeRole: data.activeRole,
roles: data.roles,
firstName: data.firstName,
lastName: data.lastName,
login: data.login,
screens: data.screens
}))
})
.catch((error: AxiosError) => {
const errorMsg = (error.response)
? responseStatusMessages[error.response.status] || 'Server application unavailable'
: 'Empty response from server'
return Observable.of($do.loginFail({ errorMsg }))
})
})
const logoutEpic: CustomEpic = (action$, store) =>
action$.ofType(actionTypes.logout).switchMap(() => {
keycloak.logout()
return Observable.of($do.logoutDone(null))
})
const logoutDone: CustomEpic = (action$, store) =>
action$.ofType(actionTypes.logoutDone).switchMap(() => {
return Observable.empty()
})
export const sessionEpics = {
ssoAuthEpic,
logoutEpic,
logoutDone,
loginEpic
}