redux-token-auth/src/actions.ts

247 lines
7.3 KiB
TypeScript
Raw Normal View History

import axios from 'axios'
import {
Dispatch,
Store,
} from 'redux'
import {
AuthResponse,
DeviceStorage,
VerificationParams,
UserAttributes,
UserRegistrationDetails,
UserSignInCredentials,
UserSignOutCredentials,
2017-09-03 13:41:20 +00:00
ActionsExport,
REGISTRATION_REQUEST_SENT,
REGISTRATION_REQUEST_SUCCEEDED,
REGISTRATION_REQUEST_FAILED,
VERIFY_TOKEN_REQUEST_SENT,
VERIFY_TOKEN_REQUEST_SUCCEEDED,
VERIFY_TOKEN_REQUEST_FAILED,
SIGNIN_REQUEST_SENT,
SIGNIN_REQUEST_SUCCEEDED,
SIGNIN_REQUEST_FAILED,
SIGNOUT_REQUEST_SENT,
SIGNOUT_REQUEST_SUCCEEDED,
SIGNOUT_REQUEST_FAILED,
RegistrationRequestSentAction,
RegistrationRequestSucceededAction,
RegistrationRequestFailedAction,
VerifyTokenRequestSentAction,
VerifyTokenRequestSucceededAction,
VerifyTokenRequestFailedAction,
SignInRequestSentAction,
SignInRequestSucceededAction,
SignInRequestFailedAction,
SignOutRequestSentAction,
SignOutRequestSucceededAction,
SignOutRequestFailedAction,
} from './types'
import AsyncLocalStorage from './AsyncLocalStorage'
import {
deleteAuthHeaders,
2017-09-27 22:08:29 +00:00
deleteAuthHeadersFromDeviceStorage,
getUserAttributesFromResponse,
persistAuthHeadersInDeviceStorage,
setAuthHeaders,
2017-09-27 22:08:29 +00:00
} from './services/auth'
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Pure Redux actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
export const registrationRequestSent = (): RegistrationRequestSentAction => ({
type: REGISTRATION_REQUEST_SENT,
})
export const registrationRequestSucceeded = (userAttributes: UserAttributes): RegistrationRequestSucceededAction => ({
type: REGISTRATION_REQUEST_SUCCEEDED,
payload: {
userAttributes,
},
})
export const registrationRequestFailed = (): RegistrationRequestFailedAction => ({
type: REGISTRATION_REQUEST_FAILED,
})
export const verifyTokenRequestSent = (): VerifyTokenRequestSentAction => ({
type: VERIFY_TOKEN_REQUEST_SENT,
})
export const verifyTokenRequestSucceeded = (userAttributes: UserAttributes): VerifyTokenRequestSucceededAction => ({
type: VERIFY_TOKEN_REQUEST_SUCCEEDED,
payload: {
userAttributes,
},
})
export const verifyTokenRequestFailed = (): VerifyTokenRequestFailedAction => ({
type: VERIFY_TOKEN_REQUEST_FAILED,
})
export const signInRequestSent = (): SignInRequestSentAction => ({
type: SIGNIN_REQUEST_SENT,
})
export const signInRequestSucceeded = (userAttributes: UserAttributes): SignInRequestSucceededAction => ({
type: SIGNIN_REQUEST_SUCCEEDED,
payload: {
userAttributes,
},
})
export const signInRequestFailed = (): SignInRequestFailedAction => ({
type: SIGNIN_REQUEST_FAILED,
})
export const signOutRequestSent = (): SignOutRequestSentAction => ({
type: SIGNOUT_REQUEST_SENT,
})
export const signOutRequestSucceeded = (): SignOutRequestSucceededAction => ({
type: SIGNOUT_REQUEST_SUCCEEDED,
})
export const signOutRequestFailed = (): SignOutRequestFailedAction => ({
type: SIGNOUT_REQUEST_FAILED,
})
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Async Redux Thunk actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2017-09-04 00:20:23 +00:00
const generateAuthActions = (config: { [key: string]: any }): ActionsExport => {
const {
authUrl,
storage,
2017-09-04 00:20:23 +00:00
userAttributes,
userRegistrationAttributes,
} = config
const Storage: DeviceStorage = Boolean(storage.flushGetRequests) ? storage : AsyncLocalStorage
const registerUser = (
userRegistrationDetails: UserRegistrationDetails,
) => async function (dispatch: Dispatch<{}>): Promise<void> {
dispatch(registrationRequestSent())
const {
email,
password,
passwordConfirmation,
} = userRegistrationDetails
2017-09-04 00:20:23 +00:00
const data = {
email,
password,
password_confirmation: passwordConfirmation,
}
Object.keys(userRegistrationAttributes).forEach((key: string) => {
const backendKey = userRegistrationAttributes[key]
data[backendKey] = userRegistrationDetails[key]
})
try {
const response: AuthResponse = await axios({
method: 'POST',
url: authUrl,
2017-09-04 00:20:23 +00:00
data,
})
setAuthHeaders(response.headers)
persistAuthHeadersInDeviceStorage(Storage, response.headers)
const userAttributesToSave = getUserAttributesFromResponse(userAttributes, response)
2017-09-27 22:08:29 +00:00
dispatch(registrationRequestSucceeded(userAttributesToSave))
} catch (error) {
dispatch(registrationRequestFailed())
throw error
}
}
const verifyToken = (
verificationParams: VerificationParams,
) => async function (dispatch: Dispatch<{}>): Promise<void> {
dispatch(verifyTokenRequestSent())
try {
const response = await axios({
method: 'GET',
url: `${authUrl}/validate_token`,
params: verificationParams,
})
setAuthHeaders(response.headers)
persistAuthHeadersInDeviceStorage(Storage, response.headers)
const userAttributesToSave = getUserAttributesFromResponse(userAttributes, response)
dispatch(verifyTokenRequestSucceeded(userAttributesToSave))
} catch (error) {
dispatch(verifyTokenRequestFailed())
}
}
const signInUser = (
userSignInCredentials: UserSignInCredentials,
) => async function (dispatch: Dispatch<{}>): Promise<void> {
dispatch(signInRequestSent())
const {
email,
password,
} = userSignInCredentials
try {
const response = await axios({
method: 'POST',
url: `${authUrl}/sign_in`,
data: {
email,
password,
},
})
setAuthHeaders(response.headers)
persistAuthHeadersInDeviceStorage(Storage, response.headers)
const userAttributesToSave = getUserAttributesFromResponse(userAttributes, response)
dispatch(signInRequestSucceeded(userAttributesToSave))
} catch (error) {
dispatch(signInRequestFailed())
throw error
}
}
const signOutUser = () => async function (dispatch: Dispatch<{}>): Promise<void> {
const userSignOutCredentials: UserSignOutCredentials = {
'access-token': await Storage.getItem('access-token') as string,
client: await Storage.getItem('client') as string,
uid: await Storage.getItem('uid') as string,
}
dispatch(signOutRequestSent())
try {
await axios({
method: 'DELETE',
url: `${authUrl}/sign_out`,
data: userSignOutCredentials,
})
deleteAuthHeaders()
2017-09-27 22:08:29 +00:00
deleteAuthHeadersFromDeviceStorage(Storage)
dispatch(signOutRequestSucceeded())
} catch (error) {
dispatch(signOutRequestFailed())
throw error
}
}
const verifyCredentials = async (store: Store<{}>): Promise<void> => {
if (await Storage.getItem('access-token')) {
const verificationParams: VerificationParams = {
'access-token': await Storage.getItem('access-token') as string,
client: await Storage.getItem('client') as string,
uid: await Storage.getItem('uid') as string,
}
store.dispatch<any>(verifyToken(verificationParams))
}
}
return {
registerUser,
verifyToken,
signInUser,
signOutUser,
verifyCredentials,
}
}
export default generateAuthActions