/redux-saga-auth

This library is a proposal of redux-saga auth flow

Primary LanguageJavaScript

This library is a proposal of redux-saga auth flow.

Reducer must be mounted at { auth } mount point.

Configuration:

import AuthSaga, { reducer as auth } from 'redux-saga-auth';

combineReducers({
  auth
})

saga.run([
  AuthSaga({ 
  saveTokens, //({ accessToken, refreshToken }) => throws error on failure
  updateAccessToken, //({ accessToken }) => throws error on failure
  resetTokens // clears tokens above, throws error on failure 
  })
])

After[login|register|logout] events are dispatched to use within other sagas to provide the flow you want for your application.

Token storage services must be provided to library sagas.

They might look like:

import invariant from 'fbjs/lib/invariant';
import { AsyncStorage } from 'react-native';

const dataKey = '@TokenData';

const accessTokenKey = `${dataKey}:accessToken`;
const refreshTokenKey = `${dataKey}:refreshToken`;

export const restoreTokens = () => {
  return Promise.all([
    AsyncStorage.getItem(accessTokenKey),
    AsyncStorage.getItem(refreshTokenKey)
  ])
    .then(data => ({ accessToken: data[0], refreshToken: data[1] }))
    .catch((error) => {
      console.log(`restore ${dataKey} error.`, error);
      return null;
    });
};

export const saveTokens = ({ accessToken, refreshToken }) => {
  invariant(accessToken, "Save tokens: Access token must be present");
  invariant(refreshToken, "Save tokens: Refresh token must be present");
  return Promise.all(
    AsyncStorage.setItem(accessTokenKey, accessToken),
    AsyncStorage.setItem(refreshTokenKey, refreshToken)
  );
};

export const updateAccessToken = ({ accessToken }) => {
  invariant(accessToken, "Update tokens: Access token must be present");
  return AsyncStorage.setItem(accessTokenKey, accessToken);
};

export const resetTokens = () => {
  return Promise.all([
    AsyncStorage.removeItem(accessTokenKey),
    AsyncStorage.removeItem(refreshTokenKey),
  ]);
};