npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@triare/auth-redux

v0.2.13

Published

redux auth

Downloads

30

Readme

Beta version

The package is designed for internal use by TRIARE. https://triare.net

The package is free and can be freely distributed

The package is written in conjunction with other company products and is part of a comprehensive solution.

How to use

Run

npm i @triare/auth-redux
yarn add @triare/auth-redux

To use it in a React project you need to create a store directory and create 2 files in it

Create files (store/index.ts and store/auth/index.ts)

Copy

store/index.ts

// example

import { combineReducers, configureStore } from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';
import { spawn } from 'redux-saga/effects';
import { EnhancedStore } from '@reduxjs/toolkit/src/configureStore';
import { moduleName as authModuleName, reducer as authReducer, saga as authSaga } from './auth';
import { moduleName as userModuleName, reducer as userReducer, saga as userSaga } from './user';
import { moduleName as commonModuleName, reducer as commonReducer, saga as commonSaga } from './common';

export const sagaMiddleware = createSagaMiddleware();

const store: EnhancedStore = configureStore({
  reducer: combineReducers({
    [authModuleName]: authReducer,
    [userModuleName]: userReducer,
    [commonModuleName]: commonReducer,
  }),
  middleware: (getDefaultMiddleware) => getDefaultMiddleware({
    thunk: false,
  }).concat([sagaMiddleware]),
  devTools: process.env.REACT_APP_ENV !== 'production',
});

export type RootState = ReturnType<typeof store.getState>;

sagaMiddleware.run(function* runSaga() {
  yield spawn(authSaga, store);
  yield spawn(commonSaga, store);
  yield spawn(userSaga);
});

export default store;

All parameters are described in the @triare/auth-redux/src/config.ts file

Reading descriptions are recommended before usage

Copy

store/auth/index.ts

// example

/* eslint-disable @typescript-eslint/no-unused-vars, no-param-reassign */

import {
  config,
  createReducers,
  State as AuthState,
  setActions,
  saga as authSaga,
  updateConfig,
  getLocalState,
  Action,
  FETCH_ME_AFTER_SUCCESS_AUTHORIZATION, createUrl,
} from '@triare/auth-redux';
import { createSlice, SliceCaseReducers } from '@reduxjs/toolkit';
import { spawn, takeLatest, put } from 'redux-saga/effects';
import { EnhancedStore } from '@reduxjs/toolkit/src/configureStore';
import { useSelector } from 'react-redux';
import { OTPResponse } from '@triare/auth-redux/dist/saga/auth/OTP';
import { SignInAction } from '@triare/auth-redux/dist/saga/auth/signIn';
import { UrlObject } from '@triare/auth-redux/src/config';
import { PayloadAction } from '@triare/auth-redux/src/saga/auth';
import { AnyObject } from '@triare/auth-redux/src/saga/common';
import { User as AuthUser } from '@triare/auth-redux/dist/saga/auth/useMe';
import { RootState } from '../index';

export * from '@triare/auth-redux';

export default updateConfig({
  fetchDelay: parseInt(process.env.REACT_APP_FETCH_DELAY || '0', 10),
  api: {
    url: process.env.REACT_APP_API || '',
  },
  signIn: {
    ...config.signIn,
    requestBody: {
    byEmail: ({ remember, ...data }: SignInAction) => JSON.stringify(data),
    byUsername: ({ remember, ...data }: SignInAction) => JSON.stringify(data),
    byPhone: ({ remember, ...data }: SignInAction) => JSON.stringify(data),
    byService: ({ method, remember, ...data }: SignInAction) => JSON.stringify(data),
  },
  fetchMeAfterSuccess: FETCH_ME_AFTER_SUCCESS_AUTHORIZATION,
  },
  OTP: {
    ...config.OTP,
    fetchMeAfterSuccess: false,
  },

  createUrl: (
    url: string | UrlObject,
    addToUrl?: string,
    payload?: PayloadAction,
    data?: AnyObject,
    _query?: AnyObject,
  ) => createUrl(url, addToUrl, payload, data, {
    ..._query,
    lang: 'en',
  }),
});

export const moduleName = config.auth.name;

export interface User extends AuthUser {
  firstName: string;
  lastName: string;
  email: string;
  phone: string;
  settings: {
    isEmailVerified: boolean;
    isPhoneVerified: boolean;
  };
}

export interface State extends AuthState {
  user: User | null;
  secretKey: string;
}

export function useAuth(): State {
  return useSelector((state: RootState) => state[moduleName]);
}

export const auth = createSlice<State, SliceCaseReducers<State>, string, SliceSelectors<State>>({
  name: moduleName,
  initialState: getLocalState<State>(),
  reducers: {
    ...createReducers(),
    signInSuccess: (state, { payload }) => {
      Object.assign(state, payload);

      state.signIn.loading = false;
      state.signIn.response = payload || null;
      state.authorized = !!(payload.access && payload.refresh);

      if (payload?.remember !== undefined) {
        state.remember = payload?.remember;
      }
    },
  },
});

export const { reducer, actions } = auth;

setActions(actions);

export function* saga(store: EnhancedStore) {
  yield spawn(authSaga, store);

  yield takeLatest(actions.OTPSuccess.toString(), function* trigger({ payload }: Action<OTPResponse>) {
    yield put({
      type: actions.signInSuccess.toString(),
      payload,
    });
  });

  // yield takeLatest(actions.userMeSuccess.toString(), function* trigger() {
  //   const authData = (yield getState()) as State;
  //
  //   if (authData && authData.user && authData.user.role === UserRoles.GUEST) {
  //     yield put(signOut());
  //
  //     window.location.href = '/sign-up';
  //   }
  // });
}

The following information describes how the auth process functioning. The general course of actions is similar for other entities.

Redux action

[nameEntity]            // Signals that the process has been called.
[nameEntity]Start       // With this event, all errors that could remain in the store are deleted and a flag is set to indicate the start of the request.
[nameEntity]Success     // Positive response from the server. Everything is fine.
[nameEntity]Error       // An error has occurred. We learn about the reason from the error field in the store.
[nameEntity]ErrorClear  // Automatically clear errors after a certain period of time. Default is 10 seconds.
[nameEntity]Clear       // Automatically clear data after a certain period of time. Default is 4 seconds.

Sign-in

// Sign-in. There are many entry options.
signIn
signInStart
signInSuccess
signInError
signInErrorClear
signInClear

List of action creators

signIn(({
  email: '[email protected]',
  password: 'string'
});

signInByUsername({
  username: 'string',
  password: 'string'
});

signInByPhone({
  phone: '+380673456789',
  password: 'string' // optional
});

signInByService({
  //              google        facebook     apple
  accessToken: access_token | accessToken | id_token,
  method: 'facebook' | 'google' | 'apple' | string
})

signInByServiceError({
  message: 'some custom error'
})

OTP

// When registering or logging in using a phone number, we will receive a code of 4 or more digits. The number of digits is not configured here.
OTP
OTPStart
OTPSuccess
OTPError
OTPErrorClear
OTPClear
// Generate new code. Code has a lifetime. After a certain time it becomes invalid.
OTPGenerate 
OTPGenerateStart
OTPGenerateSuccess
OTPGenerateError
OTPGenerateErrorClear
OTPGenerateClear

List of action creators

OTP({
  secretCode: Object.values(values).join(''),
  secretKey: 'string'
});

OTPGenerate({
  secretKey: 'string'
});

OTPGenerate({
  secretKey: 'string',
  // If you set this flag, then the code will be sent to your email.
  useEmail: true
});

Confirm

// Confirm email. Instructions with a link will be sent by email.
confirm
confirmStart
confirmSuccess
confirmError
confirmErrorClear
confirmClear

List of action creators

confirmEmail({
  secretKey: 'string',
  password: 'string' // optional - if you created an account using the fast path you must set the password
});

User-me

// After successful authorization, obtain user data.
userMe
userMeStart
userMeSuccess
userMeError
userMeErrorClear
userMeClear

List of action creators

userMe(); // does not have parameters

Sign-up

// Sign-up. There are many entry options.
signUp
signUpStart
signUpSuccess
signUpError
signUpErrorClear
signUpClear

List of action creators

signUp({
  email: 'string',
  password: 'string' // optional - easy way.
  // In this case, you will receive an email with a link. By clicking on it you will need to create a password.
  ...any else values
});

signUpByUsername({
  username: 'string',
  password: 'string'
});

signUpByPhone({
  phone: 'string',
  password: 'string' // optional
  // If you do not create a password, then you will use the confirmation code that will be sent to your phone as a password when logging in.
});

signUpByService({
  //              google        facebook     apple
  accessToken: access_token | accessToken | id_token,
  method: 'facebook' | 'google' | 'apple' | string
});

signUpByServiceError({
  message: 'some custom error'
});

Sign-out

// Delete all user data. If you want to redirect to the main page after this, subscribe to the signOutSuccess event.
signOut
signOutStart
signOutSuccess
signOutError
signOutErrorClear
signOutClear

List of action creators

signOut(); // does not have parameters

Forgot password

// Instructions with a link will be sent by email.
forgotPassword
forgotPasswordStart
forgotPasswordSuccess
forgotPasswordError
forgotPasswordErrorClear
forgotPasswordClear

List of action creators

forgotPassword({
  email: string;
});

Reset password

// Follow the link in the email and enter a new password.
resetPassword
resetPasswordStart
resetPasswordSuccess
resetPasswordError
resetPasswordErrorClear
resetPasswordClear

List of action creators

resetPassword({
  password: string;
  secretKey: string;
});

Use the following reference example, in order to send language used by the user in every request

updateConfig({

  // override function behavior
  createUrl: (
    url: string | UrlObject,    // full path
    addToUrl?: string,          // additions can come from where the function is called
    payload?: PayloadAction,    // payload action creator
    data?: AnyObject,           // data parameter that is in action
    _query?: AnyObject,         // additional parameters // the lang parameter is part of the query parameters
  ) => createUrl(url, addToUrl, payload, data, {
    ..._query,
    lang: 'en', // here use your desired language
  }),

  // OR if you need to add in the path to the endpoint

  createUrl: (
    url: string | UrlObject,
    addToUrl?: string,
    payload?: PayloadAction,
    data?: AnyObject,
    _query?: AnyObject,
  ) => createUrl(url, '/en' + addToUrl, payload, data, _query),

});